diff --git a/DEPS b/DEPS
index 863812c..236bcac 100644
--- a/DEPS
+++ b/DEPS
@@ -43,7 +43,7 @@
   # 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': '2b8fdcf7910bee068f4735015e8e122dc8e56abd',
+  'v8_revision': 'ceae85175c53e9676e869d460eddfce62ebce738',
   # 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.
@@ -267,7 +267,7 @@
 
   'src/third_party/catapult':
     Var('chromium_git') + '/external/github.com/catapult-project/catapult.git' + '@' +
-    '908ae8031f4a9b3ff663779e0375988b864c5ce9',
+    'fa891414e695f7125512449f7c49c217f85e6d8f',
 
   'src/third_party/openh264/src':
     Var('chromium_git') + '/external/github.com/cisco/openh264' + '@' + 'b37cda248234162033e3e11b0335f3131cdfe488',
diff --git a/WATCHLISTS b/WATCHLISTS
index b6ed2f0..a5b5a64 100644
--- a/WATCHLISTS
+++ b/WATCHLISTS
@@ -1472,7 +1472,8 @@
                'dennisjeffrey@chromium.org'],
     'remoting': ['chromoting-reviews@chromium.org'],
     'rlz_id': ['gab+watch@chromium.org',
-               'robertshield+watch@chromium.org'],
+               'robertshield+watch@chromium.org',
+               'alito+watch@chromium.org'],
     'safe_browsing': ['grt+watch@chromium.org'],
     'sandbox': ['rickyz+watch@chromium.org'],
     'scheduler': ['scheduler-bugs@chromium.org'],
diff --git a/ash/system/ime/ime_observer.h b/ash/system/ime/ime_observer.h
index a7f938c84..1707062 100644
--- a/ash/system/ime/ime_observer.h
+++ b/ash/system/ime/ime_observer.h
@@ -14,6 +14,12 @@
   // Notify the observer that the IME state has changed, and should be
   // refreshed.
   virtual void OnIMERefresh() = 0;
+
+  // Notify the observer that the IME menu activation state has changed, and
+  // should be refreshed. |is_active| represents whether the new IME menu is
+  // active, and IME related items in system tray should be removed if
+  // |is_active| is true.
+  virtual void OnIMEMenuActivationChanged(bool is_active) = 0;
 };
 
 }  // namespace ash
diff --git a/ash/system/ime/tray_ime_chromeos.cc b/ash/system/ime/tray_ime_chromeos.cc
index 4896a59..fad9d20 100644
--- a/ash/system/ime/tray_ime_chromeos.cc
+++ b/ash/system/ime/tray_ime_chromeos.cc
@@ -236,7 +236,8 @@
       tray_label_(NULL),
       default_(NULL),
       detailed_(NULL),
-      keyboard_suppressed_(false) {
+      keyboard_suppressed_(false),
+      is_visible_(true) {
   Shell::GetInstance()->system_tray_notifier()->AddIMEObserver(this);
   Shell::GetInstance()->system_tray_notifier()->AddVirtualKeyboardObserver(
       this);
@@ -273,7 +274,7 @@
 
 void TrayIME::UpdateTrayLabel(const IMEInfo& current, size_t count) {
   if (tray_label_) {
-    bool visible = count > 1;
+    bool visible = count > 1 && is_visible_;
     tray_label_->SetVisible(visible);
     // Do not change label before hiding because this change is noticeable.
     if (!visible)
@@ -368,9 +369,17 @@
   Update();
 }
 
+void TrayIME::OnIMEMenuActivationChanged(bool is_active) {
+  is_visible_ = !is_active;
+  if (is_visible_)
+    OnIMERefresh();
+  else
+    Update();
+}
+
 bool TrayIME::ShouldDefaultViewBeVisible() {
-  return ime_list_.size() > 1 || property_list_.size() > 1 ||
-         ShouldShowKeyboardToggle();
+  return is_visible_ && (ime_list_.size() > 1 || property_list_.size() > 1 ||
+                         ShouldShowKeyboardToggle());
 }
 
 }  // namespace ash
diff --git a/ash/system/ime/tray_ime_chromeos.h b/ash/system/ime/tray_ime_chromeos.h
index 7cf60cc..aad4afb 100644
--- a/ash/system/ime/tray_ime_chromeos.h
+++ b/ash/system/ime/tray_ime_chromeos.h
@@ -69,6 +69,7 @@
 
   // Overridden from IMEObserver.
   void OnIMERefresh() override;
+  void OnIMEMenuActivationChanged(bool is_active) override;
 
   // Whether the default view should be shown.
   bool ShouldDefaultViewBeVisible();
@@ -82,6 +83,8 @@
   IMEInfoList ime_list_;
   IMEInfo current_ime_;
   IMEPropertyInfoList property_list_;
+  // Whether the IME label and tray items should be visible.
+  bool is_visible_;
 
   DISALLOW_COPY_AND_ASSIGN(TrayIME);
 };
diff --git a/ash/system/tray/system_tray_notifier.cc b/ash/system/tray/system_tray_notifier.cc
index ec5bd8d..9432bf8 100644
--- a/ash/system/tray/system_tray_notifier.cc
+++ b/ash/system/tray/system_tray_notifier.cc
@@ -275,6 +275,12 @@
                     OnIMERefresh());
 }
 
+void SystemTrayNotifier::NotifyRefreshIMEMenu(bool is_active) {
+  FOR_EACH_OBSERVER(IMEObserver,
+                    ime_observers_,
+                    OnIMEMenuActivationChanged(is_active));
+}
+
 void SystemTrayNotifier::NotifyLocaleChanged(
     LocaleObserver::Delegate* delegate,
     const std::string& cur_locale,
diff --git a/ash/system/tray/system_tray_notifier.h b/ash/system/tray/system_tray_notifier.h
index 6e92a7d..44e7c29 100644
--- a/ash/system/tray/system_tray_notifier.h
+++ b/ash/system/tray/system_tray_notifier.h
@@ -126,6 +126,7 @@
   void NotifySystemClockTimeUpdated();
   void NotifySystemClockCanSetTimeChanged(bool can_set_time);
   void NotifyRefreshIME();
+  void NotifyRefreshIMEMenu(bool is_active);
   void NotifyLocaleChanged(LocaleObserver::Delegate* delegate,
                            const std::string& cur_locale,
                            const std::string& from_locale,
diff --git a/base/BUILD.gn b/base/BUILD.gn
index cfe258b..1fcd718 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -526,14 +526,14 @@
     "metrics/histogram_delta_serialization.h",
     "metrics/histogram_flattener.h",
     "metrics/histogram_macros.h",
-    "metrics/histogram_persistence.cc",
-    "metrics/histogram_persistence.h",
     "metrics/histogram_samples.cc",
     "metrics/histogram_samples.h",
     "metrics/histogram_snapshot_manager.cc",
     "metrics/histogram_snapshot_manager.h",
     "metrics/metrics_hashes.cc",
     "metrics/metrics_hashes.h",
+    "metrics/persistent_histogram_allocator.cc",
+    "metrics/persistent_histogram_allocator.h",
     "metrics/persistent_memory_allocator.cc",
     "metrics/persistent_memory_allocator.h",
     "metrics/sample_map.cc",
@@ -1738,6 +1738,7 @@
     "metrics/histogram_snapshot_manager_unittest.cc",
     "metrics/histogram_unittest.cc",
     "metrics/metrics_hashes_unittest.cc",
+    "metrics/persistent_histogram_allocator_unittest.cc",
     "metrics/persistent_memory_allocator_unittest.cc",
     "metrics/sample_map_unittest.cc",
     "metrics/sample_vector_unittest.cc",
diff --git a/base/base.gyp b/base/base.gyp
index 3f03dd8..d4e5be3 100644
--- a/base/base.gyp
+++ b/base/base.gyp
@@ -490,6 +490,7 @@
         'metrics/histogram_snapshot_manager_unittest.cc',
         'metrics/histogram_unittest.cc',
         'metrics/metrics_hashes_unittest.cc',
+        'metrics/persistent_histogram_allocator_unittest.cc',
         'metrics/persistent_memory_allocator_unittest.cc',
         'metrics/sample_map_unittest.cc',
         'metrics/sample_vector_unittest.cc',
diff --git a/base/base.gypi b/base/base.gypi
index efcd8a3..4bf8ae61 100644
--- a/base/base.gypi
+++ b/base/base.gypi
@@ -406,14 +406,14 @@
           'metrics/histogram_delta_serialization.h',
           'metrics/histogram_flattener.h',
           'metrics/histogram_macros.h',
-          'metrics/histogram_persistence.cc',
-          'metrics/histogram_persistence.h',
           'metrics/histogram_samples.cc',
           'metrics/histogram_samples.h',
           'metrics/histogram_snapshot_manager.cc',
           'metrics/histogram_snapshot_manager.h',
           'metrics/metrics_hashes.cc',
           'metrics/metrics_hashes.h',
+          'metrics/persistent_histogram_allocator.cc',
+          'metrics/persistent_histogram_allocator.h',
           'metrics/persistent_memory_allocator.cc',
           'metrics/persistent_memory_allocator.h',
           'metrics/sample_map.cc',
diff --git a/base/memory/weak_ptr.h b/base/memory/weak_ptr.h
index 9ba5e25c..006e1fd3 100644
--- a/base/memory/weak_ptr.h
+++ b/base/memory/weak_ptr.h
@@ -161,10 +161,9 @@
   // function that makes calling this easier.
   template<typename Derived>
   static WeakPtr<Derived> StaticAsWeakPtr(Derived* t) {
-    using convertible =
-        std::is_convertible<Derived*, internal::SupportsWeakPtrBase*>;
-    static_assert(convertible::value,
-                  "AsWeakPtr argument must inherit from SupportsWeakPtr");
+    static_assert(
+        std::is_base_of<internal::SupportsWeakPtrBase, Derived>::value,
+        "AsWeakPtr argument must inherit from SupportsWeakPtr");
     return AsWeakPtrImpl<Derived>(t, *t);
   }
 
diff --git a/base/memory/weak_ptr_unittest.nc b/base/memory/weak_ptr_unittest.nc
index bad1c97e..32deca9 100644
--- a/base/memory/weak_ptr_unittest.nc
+++ b/base/memory/weak_ptr_unittest.nc
@@ -129,7 +129,7 @@
   WeakPtr<Unrelated> ptr = AsWeakPtr(&f);
 }
 
-#elif defined(NCTEST_AMBIGUOUS_ANCESTORS)  // [r"fatal error: ambiguous conversion from derived class 'base::MultiplyDerivedProducer' to base class 'base::internal::SupportsWeakPtrBase':"]
+#elif defined(NCTEST_AMBIGUOUS_ANCESTORS)  // [r"fatal error: member 'AsWeakPtr' found in multiple base classes of different types"]
 
 void WontCompile() {
   MultiplyDerivedProducer f;
diff --git a/base/metrics/histogram.cc b/base/metrics/histogram.cc
index ea4f816..e8d851bf9 100644
--- a/base/metrics/histogram.cc
+++ b/base/metrics/histogram.cc
@@ -19,8 +19,8 @@
 #include "base/debug/alias.h"
 #include "base/logging.h"
 #include "base/metrics/histogram_macros.h"
-#include "base/metrics/histogram_persistence.h"
 #include "base/metrics/metrics_hashes.h"
+#include "base/metrics/persistent_histogram_allocator.h"
 #include "base/metrics/persistent_memory_allocator.h"
 #include "base/metrics/sample_vector.h"
 #include "base/metrics/statistics_recorder.h"
@@ -122,8 +122,8 @@
 
   // Allocate the correct Histogram object off the heap (in case persistent
   // memory is not available).
-  virtual HistogramBase* HeapAlloc(const BucketRanges* ranges) {
-    return new Histogram(name_, minimum_, maximum_, ranges);
+  virtual scoped_ptr<HistogramBase> HeapAlloc(const BucketRanges* ranges) {
+    return make_scoped_ptr(new Histogram(name_, minimum_, maximum_, ranges));
   }
 
   // Perform any required datafill on the just-created histogram.  If
@@ -151,7 +151,7 @@
   // been added by other processes and they must be fetched and recognized
   // locally in order to be found by FindHistograms() below. If the persistent
   // memory segment is not shared between processes, this call does nothing.
-  ImportPersistentHistograms();
+  PersistentHistogramAllocator::ImportGlobalHistograms();
 
   HistogramBase* histogram = StatisticsRecorder::FindHistogram(name_);
   if (!histogram) {
@@ -176,14 +176,13 @@
     // that is off by default. If the allocator doesn't exist or if
     // allocating from it fails, code below will allocate the histogram from
     // the process heap.
-    PersistentMemoryAllocator::Reference histogram_ref = 0;
-    HistogramBase* tentative_histogram = nullptr;
-    PersistentMemoryAllocator* allocator =
-        GetPersistentHistogramMemoryAllocator();
+    PersistentHistogramAllocator::Reference histogram_ref = 0;
+    scoped_ptr<HistogramBase> tentative_histogram;
+    PersistentHistogramAllocator* allocator =
+        PersistentHistogramAllocator::GetGlobalAllocator();
     if (allocator) {
       flags_ |= HistogramBase::kIsPersistent;
-      tentative_histogram = AllocatePersistentHistogram(
-          allocator,
+      tentative_histogram = allocator->AllocateHistogram(
           histogram_type_,
           name_,
           minimum_,
@@ -202,14 +201,20 @@
       tentative_histogram = HeapAlloc(registered_ranges);
     }
 
-    FillHistogram(tentative_histogram);
-    histogram =
-        StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram);
+    FillHistogram(tentative_histogram.get());
+
+    // Register this histogram with the StatisticsRecorder. Keep a copy of
+    // the pointer value to tell later whether the locally created histogram
+    // was registered or deleted. The type is "void" because it could point
+    // to released memory after the following line.
+    const void* tentative_histogram_ptr = tentative_histogram.get();
+    histogram = StatisticsRecorder::RegisterOrDeleteDuplicate(
+        tentative_histogram.release());
 
     // Persistent histograms need some follow-up processing.
     if (histogram_ref) {
-      FinalizePersistentHistogram(histogram_ref,
-                                  histogram == tentative_histogram);
+      allocator->FinalizeHistogram(histogram_ref,
+                                   histogram == tentative_histogram_ptr);
     }
   }
 
@@ -267,7 +272,7 @@
                         flags);
 }
 
-HistogramBase* Histogram::PersistentGet(
+scoped_ptr<HistogramBase> Histogram::PersistentCreate(
     const std::string& name,
     Sample minimum,
     Sample maximum,
@@ -277,8 +282,9 @@
     uint32_t counts_size,
     HistogramSamples::Metadata* meta,
     HistogramSamples::Metadata* logged_meta) {
-  return new Histogram(name, minimum, maximum, ranges, counts, logged_counts,
-                       counts_size, meta, logged_meta);
+  return make_scoped_ptr(new Histogram(
+      name, minimum, maximum, ranges, counts, logged_counts, counts_size,
+      meta, logged_meta));
 }
 
 // Calculate what range of values are held in each bucket.
@@ -732,8 +738,9 @@
     return ranges;
   }
 
-  HistogramBase* HeapAlloc(const BucketRanges* ranges) override {
-    return new LinearHistogram(name_, minimum_, maximum_, ranges);
+  scoped_ptr<HistogramBase> HeapAlloc(const BucketRanges* ranges) override {
+    return make_scoped_ptr(
+        new LinearHistogram(name_, minimum_, maximum_, ranges));
   }
 
   void FillHistogram(HistogramBase* base_histogram) override {
@@ -792,7 +799,7 @@
                         flags);
 }
 
-HistogramBase* LinearHistogram::PersistentGet(
+scoped_ptr<HistogramBase> LinearHistogram::PersistentCreate(
     const std::string& name,
     Sample minimum,
     Sample maximum,
@@ -802,8 +809,9 @@
     uint32_t counts_size,
     HistogramSamples::Metadata* meta,
     HistogramSamples::Metadata* logged_meta) {
-  return new LinearHistogram(name, minimum, maximum, ranges, counts,
-                             logged_counts, counts_size, meta, logged_meta);
+  return make_scoped_ptr(new LinearHistogram(
+      name, minimum, maximum, ranges, counts, logged_counts, counts_size,
+      meta, logged_meta));
 }
 
 HistogramBase* LinearHistogram::FactoryGetWithRangeDescription(
@@ -921,8 +929,8 @@
     return ranges;
   }
 
-  HistogramBase* HeapAlloc(const BucketRanges* ranges) override {
-    return new BooleanHistogram(name_, ranges);
+  scoped_ptr<HistogramBase> HeapAlloc(const BucketRanges* ranges) override {
+    return make_scoped_ptr(new BooleanHistogram(name_, ranges));
   }
 
  private:
@@ -938,15 +946,15 @@
   return FactoryGet(std::string(name), flags);
 }
 
-HistogramBase* BooleanHistogram::PersistentGet(
+scoped_ptr<HistogramBase> BooleanHistogram::PersistentCreate(
     const std::string& name,
     const BucketRanges* ranges,
     HistogramBase::AtomicCount* counts,
     HistogramBase::AtomicCount* logged_counts,
     HistogramSamples::Metadata* meta,
     HistogramSamples::Metadata* logged_meta) {
-  return new BooleanHistogram(name, ranges, counts, logged_counts, meta,
-                              logged_meta);
+  return make_scoped_ptr(new BooleanHistogram(
+      name, ranges, counts, logged_counts, meta, logged_meta));
 }
 
 HistogramType BooleanHistogram::GetHistogramType() const {
@@ -1018,8 +1026,8 @@
     return bucket_ranges;
   }
 
-  HistogramBase* HeapAlloc(const BucketRanges* ranges) override {
-    return new CustomHistogram(name_, ranges);
+  scoped_ptr<HistogramBase> HeapAlloc(const BucketRanges* ranges) override {
+    return make_scoped_ptr(new CustomHistogram(name_, ranges));
   }
 
  private:
@@ -1044,7 +1052,7 @@
   return FactoryGet(std::string(name), custom_ranges, flags);
 }
 
-HistogramBase* CustomHistogram::PersistentGet(
+scoped_ptr<HistogramBase> CustomHistogram::PersistentCreate(
     const std::string& name,
     const BucketRanges* ranges,
     HistogramBase::AtomicCount* counts,
@@ -1052,8 +1060,8 @@
     uint32_t counts_size,
     HistogramSamples::Metadata* meta,
     HistogramSamples::Metadata* logged_meta) {
-  return new CustomHistogram(name, ranges, counts, logged_counts, counts_size,
-                             meta, logged_meta);
+  return make_scoped_ptr(new CustomHistogram(
+      name, ranges, counts, logged_counts, counts_size, meta, logged_meta));
 }
 
 HistogramType CustomHistogram::GetHistogramType() const {
diff --git a/base/metrics/histogram.h b/base/metrics/histogram.h
index ea59de64..5111b8f 100644
--- a/base/metrics/histogram.h
+++ b/base/metrics/histogram.h
@@ -104,6 +104,8 @@
 
   typedef std::vector<Count> Counts;
 
+  ~Histogram() override;
+
   //----------------------------------------------------------------------------
   // For a valid histogram, input should follow these restrictions:
   // minimum > 0 (if a minimum below 1 is specified, it will implicitly be
@@ -139,16 +141,17 @@
                                        uint32_t bucket_count,
                                        int32_t flags);
 
-  // Get a histogram using data in persistent storage.
-  static HistogramBase* PersistentGet(const std::string& name,
-                                      Sample minimum,
-                                      Sample maximum,
-                                      const BucketRanges* ranges,
-                                      HistogramBase::AtomicCount* counts,
-                                      HistogramBase::AtomicCount* logged_counts,
-                                      uint32_t counts_size,
-                                      HistogramSamples::Metadata* meta,
-                                      HistogramSamples::Metadata* logged_meta);
+  // Create a histogram using data in persistent storage.
+  static scoped_ptr<HistogramBase> PersistentCreate(
+      const std::string& name,
+      Sample minimum,
+      Sample maximum,
+      const BucketRanges* ranges,
+      HistogramBase::AtomicCount* counts,
+      HistogramBase::AtomicCount* logged_counts,
+      uint32_t counts_size,
+      HistogramSamples::Metadata* meta,
+      HistogramSamples::Metadata* logged_meta);
 
   static void InitializeBucketRanges(Sample minimum,
                                      Sample maximum,
@@ -237,8 +240,6 @@
             HistogramSamples::Metadata* meta,
             HistogramSamples::Metadata* logged_meta);
 
-  ~Histogram() override;
-
   // HistogramBase implementation:
   bool SerializeInfoImpl(base::Pickle* pickle) const override;
 
@@ -350,16 +351,17 @@
                                        uint32_t bucket_count,
                                        int32_t flags);
 
-  // Get a histogram using data in persistent storage.
-  static HistogramBase* PersistentGet(const std::string& name,
-                                      Sample minimum,
-                                      Sample maximum,
-                                      const BucketRanges* ranges,
-                                      HistogramBase::AtomicCount* counts,
-                                      HistogramBase::AtomicCount* logged_counts,
-                                      uint32_t counts_size,
-                                      HistogramSamples::Metadata* meta,
-                                      HistogramSamples::Metadata* logged_meta);
+  // Create a histogram using data in persistent storage.
+  static scoped_ptr<HistogramBase> PersistentCreate(
+      const std::string& name,
+      Sample minimum,
+      Sample maximum,
+      const BucketRanges* ranges,
+      HistogramBase::AtomicCount* counts,
+      HistogramBase::AtomicCount* logged_counts,
+      uint32_t counts_size,
+      HistogramSamples::Metadata* meta,
+      HistogramSamples::Metadata* logged_meta);
 
   struct DescriptionPair {
     Sample sample;
@@ -440,13 +442,14 @@
   // call sites.
   static HistogramBase* FactoryGet(const char* name, int32_t flags);
 
-  // Get a histogram using data in persistent storage.
-  static HistogramBase* PersistentGet(const std::string& name,
-                                      const BucketRanges* ranges,
-                                      HistogramBase::AtomicCount* counts,
-                                      HistogramBase::AtomicCount* logged_counts,
-                                      HistogramSamples::Metadata* meta,
-                                      HistogramSamples::Metadata* logged_meta);
+  // Create a histogram using data in persistent storage.
+  static scoped_ptr<HistogramBase> PersistentCreate(
+      const std::string& name,
+      const BucketRanges* ranges,
+      HistogramBase::AtomicCount* counts,
+      HistogramBase::AtomicCount* logged_counts,
+      HistogramSamples::Metadata* meta,
+      HistogramSamples::Metadata* logged_meta);
 
   HistogramType GetHistogramType() const override;
 
@@ -489,14 +492,15 @@
                                    const std::vector<Sample>& custom_ranges,
                                    int32_t flags);
 
-  // Get a histogram using data in persistent storage.
-  static HistogramBase* PersistentGet(const std::string& name,
-                                      const BucketRanges* ranges,
-                                      HistogramBase::AtomicCount* counts,
-                                      HistogramBase::AtomicCount* logged_counts,
-                                      uint32_t counts_size,
-                                      HistogramSamples::Metadata* meta,
-                                      HistogramSamples::Metadata* logged_meta);
+  // Create a histogram using data in persistent storage.
+  static scoped_ptr<HistogramBase> PersistentCreate(
+      const std::string& name,
+      const BucketRanges* ranges,
+      HistogramBase::AtomicCount* counts,
+      HistogramBase::AtomicCount* logged_counts,
+      uint32_t counts_size,
+      HistogramSamples::Metadata* meta,
+      HistogramSamples::Metadata* logged_meta);
 
   // Overridden from Histogram:
   HistogramType GetHistogramType() const override;
diff --git a/base/metrics/histogram_persistence.cc b/base/metrics/histogram_persistence.cc
deleted file mode 100644
index f18d175..0000000
--- a/base/metrics/histogram_persistence.cc
+++ /dev/null
@@ -1,516 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/metrics/histogram_persistence.h"
-
-#include "base/lazy_instance.h"
-#include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/metrics/histogram.h"
-#include "base/metrics/histogram_base.h"
-#include "base/metrics/histogram_samples.h"
-#include "base/metrics/statistics_recorder.h"
-#include "base/synchronization/lock.h"
-
-namespace base {
-
-namespace {
-
-// Enumerate possible creation results for reporting.
-enum CreateHistogramResultType {
-  // Everything was fine.
-  CREATE_HISTOGRAM_SUCCESS = 0,
-
-  // Pointer to metadata was not valid.
-  CREATE_HISTOGRAM_INVALID_METADATA_POINTER,
-
-  // Histogram metadata was not valid.
-  CREATE_HISTOGRAM_INVALID_METADATA,
-
-  // Ranges information was not valid.
-  CREATE_HISTOGRAM_INVALID_RANGES_ARRAY,
-
-  // Counts information was not valid.
-  CREATE_HISTOGRAM_INVALID_COUNTS_ARRAY,
-
-  // Could not allocate histogram memory due to corruption.
-  CREATE_HISTOGRAM_ALLOCATOR_CORRUPT,
-
-  // Could not allocate histogram memory due to lack of space.
-  CREATE_HISTOGRAM_ALLOCATOR_FULL,
-
-  // Could not allocate histogram memory due to unknown error.
-  CREATE_HISTOGRAM_ALLOCATOR_ERROR,
-
-  // Histogram was of unknown type.
-  CREATE_HISTOGRAM_UNKNOWN_TYPE,
-
-  // Instance has detected a corrupt allocator (recorded only once).
-  CREATE_HISTOGRAM_ALLOCATOR_NEWLY_CORRUPT,
-
-  // Always keep this at the end.
-  CREATE_HISTOGRAM_MAX
-};
-
-// Name of histogram for storing results of local operations.
-const char kResultHistogram[] = "UMA.CreatePersistentHistogram.Result";
-
-// Type identifiers used when storing in persistent memory so they can be
-// identified during extraction; the first 4 bytes of the SHA1 of the name
-// is used as a unique integer. A "version number" is added to the base
-// so that, if the structure of that object changes, stored older versions
-// will be safely ignored.
-enum : uint32_t {
-  kTypeIdHistogram   = 0xF1645910 + 2,  // SHA1(Histogram) v2
-  kTypeIdRangesArray = 0xBCEA225A + 1,  // SHA1(RangesArray) v1
-  kTypeIdCountsArray = 0x53215530 + 1,  // SHA1(CountsArray) v1
-};
-
-// This data must be held in persistent memory in order for processes to
-// locate and use histograms created elsewhere. All elements must be of a
-// fixed width to ensure 32/64-bit interoperability.
-struct PersistentHistogramData {
-  int32_t histogram_type;
-  int32_t flags;
-  int32_t minimum;
-  int32_t maximum;
-  uint32_t bucket_count;
-  PersistentMemoryAllocator::Reference ranges_ref;
-  uint32_t ranges_checksum;
-  PersistentMemoryAllocator::Reference counts_ref;
-  HistogramSamples::Metadata samples_metadata;
-  HistogramSamples::Metadata logged_metadata;
-
-  // Space for the histogram name will be added during the actual allocation
-  // request. This must be the last field of the structure. A zero-size array
-  // or a "flexible" array would be preferred but is not (yet) valid C++.
-  char name[1];
-};
-
-// The object held here will obviously not be destructed at process exit
-// but that's okay since PersistentMemoryAllocator objects are explicitly
-// forbidden from doing anything essential at exit anyway due to the fact
-// that they depend on data managed elsewhere and which could be destructed
-// first.
-PersistentMemoryAllocator* g_allocator = nullptr;
-
-// Take an array of range boundaries and create a proper BucketRanges object
-// which is returned to the caller. A return of nullptr indicates that the
-// passed boundaries are invalid.
-BucketRanges* CreateRangesFromData(HistogramBase::Sample* ranges_data,
-                                   uint32_t ranges_checksum,
-                                   size_t count) {
-  scoped_ptr<BucketRanges> ranges(new BucketRanges(count));
-  DCHECK_EQ(count, ranges->size());
-  for (size_t i = 0; i < count; ++i) {
-    if (i > 0 && ranges_data[i] <= ranges_data[i - 1])
-      return nullptr;
-    ranges->set_range(i, ranges_data[i]);
-  }
-
-  ranges->ResetChecksum();
-  if (ranges->checksum() != ranges_checksum)
-    return nullptr;
-
-  return ranges.release();
-}
-
-// Calculate the number of bytes required to store all of a histogram's
-// "counts". This will return zero (0) if |bucket_count| is not valid.
-size_t CalculateRequiredCountsBytes(size_t bucket_count) {
-  // 2 because each "sample count" also requires a backup "logged count"
-  // used for calculating the delta during snapshot operations.
-  const unsigned kBytesPerBucket = 2 * sizeof(HistogramBase::AtomicCount);
-
-  // If the |bucket_count| is such that it would overflow the return type,
-  // perhaps as the result of a malicious actor, then return zero to
-  // indicate the problem to the caller.
-  if (bucket_count > std::numeric_limits<uint32_t>::max() / kBytesPerBucket)
-    return 0;
-
-  return bucket_count * kBytesPerBucket;
-}
-
-}  // namespace
-
-const Feature kPersistentHistogramsFeature{
-  "PersistentHistograms", FEATURE_DISABLED_BY_DEFAULT
-};
-
-// Get the histogram in which create results are stored. This is copied almost
-// exactly from the STATIC_HISTOGRAM_POINTER_BLOCK macro but with added code
-// to prevent recursion (a likely occurance because the creation of a new
-// histogram can end up calling this.)
-HistogramBase* GetCreateHistogramResultHistogram() {
-  static base::subtle::AtomicWord atomic_histogram_pointer = 0;
-  HistogramBase* histogram_pointer(
-      reinterpret_cast<HistogramBase*>(
-          base::subtle::Acquire_Load(&atomic_histogram_pointer)));
-  if (!histogram_pointer) {
-    // It's possible for multiple threads to make it here in parallel but
-    // they'll always return the same result as there is a mutex in the Get.
-    // The purpose of the "initialized" variable is just to ensure that
-    // the same thread doesn't recurse which is also why it doesn't have
-    // to be atomic.
-    static bool initialized = false;
-    if (!initialized) {
-      initialized = true;
-      if (g_allocator) {
-        DLOG(WARNING) << "Creating the results-histogram inside persistent"
-                      << " memory can cause future allocations to crash if"
-                      << " that memory is ever released (for testing).";
-      }
-
-      histogram_pointer = LinearHistogram::FactoryGet(
-          kResultHistogram, 1, CREATE_HISTOGRAM_MAX, CREATE_HISTOGRAM_MAX + 1,
-          HistogramBase::kUmaTargetedHistogramFlag);
-      base::subtle::Release_Store(
-          &atomic_histogram_pointer,
-          reinterpret_cast<base::subtle::AtomicWord>(histogram_pointer));
-    }
-  }
-  return histogram_pointer;
-}
-
-// Record the result of a histogram creation.
-void RecordCreateHistogramResult(CreateHistogramResultType result) {
-  HistogramBase* result_histogram = GetCreateHistogramResultHistogram();
-  if (result_histogram)
-    result_histogram->Add(result);
-}
-
-void SetPersistentHistogramMemoryAllocator(
-    PersistentMemoryAllocator* allocator) {
-  // Releasing or changing an allocator is extremely dangerous because it
-  // likely has histograms stored within it. If the backing memory is also
-  // also released, future accesses to those histograms will seg-fault.
-  CHECK(!g_allocator);
-  g_allocator = allocator;
-}
-
-PersistentMemoryAllocator* GetPersistentHistogramMemoryAllocator() {
-  return g_allocator;
-}
-
-PersistentMemoryAllocator*
-ReleasePersistentHistogramMemoryAllocatorForTesting() {
-  PersistentMemoryAllocator* allocator = g_allocator;
-  if (!allocator)
-    return nullptr;
-
-  // Before releasing the memory, it's necessary to have the Statistics-
-  // Recorder forget about the histograms contained therein; otherwise,
-  // some operations will try to access them and the released memory.
-  PersistentMemoryAllocator::Iterator iter;
-  PersistentMemoryAllocator::Reference ref;
-  uint32_t type_id;
-  allocator->CreateIterator(&iter);
-  while ((ref = allocator->GetNextIterable(&iter, &type_id)) != 0) {
-    if (type_id == kTypeIdHistogram) {
-      PersistentHistogramData* histogram_data =
-          allocator->GetAsObject<PersistentHistogramData>(
-              ref, kTypeIdHistogram);
-      DCHECK(histogram_data);
-      StatisticsRecorder::ForgetHistogramForTesting(histogram_data->name);
-
-      // If a test breaks here then a memory region containing a histogram
-      // actively used by this code is being released back to the test.
-      // If that memory segment were to be deleted, future calls to create
-      // persistent histograms would crash. To avoid this, have the test call
-      // the method GetCreateHistogramResultHistogram() *before* setting the
-      // (temporary) memory allocator via SetPersistentMemoryAllocator() so
-      // that the histogram is instead allocated from the process heap.
-      DCHECK_NE(kResultHistogram, histogram_data->name);
-    }
-  }
-
-  g_allocator = nullptr;
-  return allocator;
-};
-
-HistogramBase* CreatePersistentHistogram(
-    PersistentMemoryAllocator* allocator,
-    PersistentHistogramData* histogram_data_ptr) {
-  if (!histogram_data_ptr) {
-    RecordCreateHistogramResult(CREATE_HISTOGRAM_INVALID_METADATA_POINTER);
-    NOTREACHED();
-    return nullptr;
-  }
-
-  // Copy the histogram_data to local storage because anything in persistent
-  // memory cannot be trusted as it could be changed at any moment by a
-  // malicious actor that shares access. The contents of histogram_data are
-  // validated below; the local copy is to ensure that the contents cannot
-  // be externally changed between validation and use.
-  PersistentHistogramData histogram_data = *histogram_data_ptr;
-
-  HistogramBase::Sample* ranges_data =
-      allocator->GetAsObject<HistogramBase::Sample>(histogram_data.ranges_ref,
-                                                    kTypeIdRangesArray);
-  if (!ranges_data || histogram_data.bucket_count < 2 ||
-      histogram_data.bucket_count + 1 >
-          std::numeric_limits<uint32_t>::max() /
-              sizeof(HistogramBase::Sample) ||
-      allocator->GetAllocSize(histogram_data.ranges_ref) <
-          (histogram_data.bucket_count + 1) * sizeof(HistogramBase::Sample)) {
-    RecordCreateHistogramResult(CREATE_HISTOGRAM_INVALID_RANGES_ARRAY);
-    NOTREACHED();
-    return nullptr;
-  }
-  // To avoid racy destruction at shutdown, the following will be leaked.
-  const BucketRanges* ranges = CreateRangesFromData(
-      ranges_data,
-      histogram_data.ranges_checksum,
-      histogram_data.bucket_count + 1);
-  if (!ranges) {
-    RecordCreateHistogramResult(CREATE_HISTOGRAM_INVALID_RANGES_ARRAY);
-    NOTREACHED();
-    return nullptr;
-  }
-  ranges = StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges);
-
-  HistogramBase::AtomicCount* counts_data =
-      allocator->GetAsObject<HistogramBase::AtomicCount>(
-          histogram_data.counts_ref, kTypeIdCountsArray);
-  size_t counts_bytes =
-      CalculateRequiredCountsBytes(histogram_data.bucket_count);
-  if (!counts_data || !counts_bytes ||
-      allocator->GetAllocSize(histogram_data.counts_ref) < counts_bytes) {
-    RecordCreateHistogramResult(CREATE_HISTOGRAM_INVALID_COUNTS_ARRAY);
-    NOTREACHED();
-    return nullptr;
-  }
-
-  // After the main "counts" array is a second array using for storing what
-  // was previously logged. This is used to calculate the "delta" during
-  // snapshot operations.
-  HistogramBase::AtomicCount* logged_data =
-      counts_data + histogram_data.bucket_count;
-
-  std::string name(histogram_data_ptr->name);
-  HistogramBase* histogram = nullptr;
-  switch (histogram_data.histogram_type) {
-    case HISTOGRAM:
-      histogram = Histogram::PersistentGet(
-          name,
-          histogram_data.minimum,
-          histogram_data.maximum,
-          ranges,
-          counts_data,
-          logged_data,
-          histogram_data.bucket_count,
-          &histogram_data_ptr->samples_metadata,
-          &histogram_data_ptr->logged_metadata);
-      DCHECK(histogram);
-      break;
-    case LINEAR_HISTOGRAM:
-      histogram = LinearHistogram::PersistentGet(
-          name,
-          histogram_data.minimum,
-          histogram_data.maximum,
-          ranges,
-          counts_data,
-          logged_data,
-          histogram_data.bucket_count,
-          &histogram_data_ptr->samples_metadata,
-          &histogram_data_ptr->logged_metadata);
-      DCHECK(histogram);
-      break;
-    case BOOLEAN_HISTOGRAM:
-      histogram = BooleanHistogram::PersistentGet(
-          name,
-          ranges,
-          counts_data,
-          logged_data,
-          &histogram_data_ptr->samples_metadata,
-          &histogram_data_ptr->logged_metadata);
-      DCHECK(histogram);
-      break;
-    case CUSTOM_HISTOGRAM:
-      histogram = CustomHistogram::PersistentGet(
-          name,
-          ranges,
-          counts_data,
-          logged_data,
-          histogram_data.bucket_count,
-          &histogram_data_ptr->samples_metadata,
-          &histogram_data_ptr->logged_metadata);
-      DCHECK(histogram);
-      break;
-    default:
-      NOTREACHED();
-  }
-
-  if (histogram) {
-    DCHECK_EQ(histogram_data.histogram_type, histogram->GetHistogramType());
-    histogram->SetFlags(histogram_data.flags);
-    RecordCreateHistogramResult(CREATE_HISTOGRAM_SUCCESS);
-  } else {
-    RecordCreateHistogramResult(CREATE_HISTOGRAM_UNKNOWN_TYPE);
-  }
-
-  return histogram;
-}
-
-HistogramBase* GetPersistentHistogram(
-    PersistentMemoryAllocator* allocator,
-    int32_t ref) {
-  // Unfortunately, the above "pickle" methods cannot be used as part of the
-  // persistance because the deserialization methods always create local
-  // count data (these must referenced the persistent counts) and always add
-  // it to the local list of known histograms (these may be simple references
-  // to histograms in other processes).
-  PersistentHistogramData* histogram_data =
-      allocator->GetAsObject<PersistentHistogramData>(ref, kTypeIdHistogram);
-  size_t length = allocator->GetAllocSize(ref);
-  if (!histogram_data ||
-      reinterpret_cast<char*>(histogram_data)[length - 1] != '\0') {
-    RecordCreateHistogramResult(CREATE_HISTOGRAM_INVALID_METADATA);
-    NOTREACHED();
-    return nullptr;
-  }
-  return CreatePersistentHistogram(allocator, histogram_data);
-}
-
-HistogramBase* GetNextPersistentHistogram(
-    PersistentMemoryAllocator* allocator,
-    PersistentMemoryAllocator::Iterator* iter) {
-  PersistentMemoryAllocator::Reference ref;
-  uint32_t type_id;
-  while ((ref = allocator->GetNextIterable(iter, &type_id)) != 0) {
-    if (type_id == kTypeIdHistogram)
-      return GetPersistentHistogram(allocator, ref);
-  }
-  return nullptr;
-}
-
-void FinalizePersistentHistogram(PersistentMemoryAllocator::Reference ref,
-                                 bool registered) {
-  // If the created persistent histogram was registered then it needs to
-  // be marked as "iterable" in order to be found by other processes.
-  if (registered)
-    GetPersistentHistogramMemoryAllocator()->MakeIterable(ref);
-  // If it wasn't registered then a race condition must have caused
-  // two to be created. The allocator does not support releasing the
-  // acquired memory so just change the type to be empty.
-  else
-    GetPersistentHistogramMemoryAllocator()->SetType(ref, 0);
-}
-
-HistogramBase* AllocatePersistentHistogram(
-    PersistentMemoryAllocator* allocator,
-    HistogramType histogram_type,
-    const std::string& name,
-    int minimum,
-    int maximum,
-    const BucketRanges* bucket_ranges,
-    int32_t flags,
-    PersistentMemoryAllocator::Reference* ref_ptr) {
-  if (!allocator)
-    return nullptr;
-
-  // If the allocator is corrupt, don't waste time trying anything else.
-  // This also allows differentiating on the dashboard between allocations
-  // failed due to a corrupt allocator and the number of process instances
-  // with one, the latter being idicated by "newly corrupt", below.
-  if (allocator->IsCorrupt()) {
-    RecordCreateHistogramResult(CREATE_HISTOGRAM_ALLOCATOR_CORRUPT);
-    return nullptr;
-  }
-
-  // If CalculateRequiredCountsBytes() returns zero then the bucket_count
-  // was not valid.
-  size_t bucket_count = bucket_ranges->bucket_count();
-  size_t counts_bytes = CalculateRequiredCountsBytes(bucket_count);
-  if (!counts_bytes) {
-    NOTREACHED();
-    return nullptr;
-  }
-
-  size_t ranges_bytes = (bucket_count + 1) * sizeof(HistogramBase::Sample);
-  PersistentMemoryAllocator::Reference ranges_ref =
-      allocator->Allocate(ranges_bytes, kTypeIdRangesArray);
-  PersistentMemoryAllocator::Reference counts_ref =
-      allocator->Allocate(counts_bytes, kTypeIdCountsArray);
-  PersistentMemoryAllocator::Reference histogram_ref =
-      allocator->Allocate(offsetof(PersistentHistogramData, name) +
-                          name.length() + 1, kTypeIdHistogram);
-  HistogramBase::Sample* ranges_data =
-      allocator->GetAsObject<HistogramBase::Sample>(ranges_ref,
-                                                    kTypeIdRangesArray);
-  PersistentHistogramData* histogram_data =
-      allocator->GetAsObject<PersistentHistogramData>(histogram_ref,
-                                                      kTypeIdHistogram);
-
-  // Only continue here if all allocations were successful. If they weren't
-  // there is no way to free the space but that's not really a problem since
-  // the allocations only fail because the space is full and so any future
-  // attempts will also fail.
-  if (counts_ref && ranges_data && histogram_data) {
-    strcpy(histogram_data->name, name.c_str());
-    for (size_t i = 0; i < bucket_ranges->size(); ++i)
-      ranges_data[i] = bucket_ranges->range(i);
-
-    histogram_data->histogram_type = histogram_type;
-    histogram_data->flags = flags;
-    histogram_data->minimum = minimum;
-    histogram_data->maximum = maximum;
-    histogram_data->bucket_count = static_cast<uint32_t>(bucket_count);
-    histogram_data->ranges_ref = ranges_ref;
-    histogram_data->ranges_checksum = bucket_ranges->checksum();
-    histogram_data->counts_ref = counts_ref;
-
-    // Create the histogram using resources in persistent memory. This ends up
-    // resolving the "ref" values stored in histogram_data instad of just
-    // using what is already known above but avoids duplicating the switch
-    // statement here and serves as a double-check that everything is
-    // correct before commiting the new histogram to persistent space.
-    HistogramBase* histogram =
-        CreatePersistentHistogram(allocator, histogram_data);
-    DCHECK(histogram);
-    if (ref_ptr != nullptr)
-      *ref_ptr = histogram_ref;
-    return histogram;
-  }
-
-  CreateHistogramResultType result;
-  if (allocator->IsCorrupt()) {
-    RecordCreateHistogramResult(CREATE_HISTOGRAM_ALLOCATOR_NEWLY_CORRUPT);
-    result = CREATE_HISTOGRAM_ALLOCATOR_CORRUPT;
-  } else if (allocator->IsFull()) {
-    result = CREATE_HISTOGRAM_ALLOCATOR_FULL;
-  } else {
-    result = CREATE_HISTOGRAM_ALLOCATOR_ERROR;
-  }
-  RecordCreateHistogramResult(result);
-  NOTREACHED() << "error=" << result;
-
-  return nullptr;
-}
-
-void ImportPersistentHistograms() {
-  // The lock protects against concurrent access to the iterator and is created
-  // in a thread-safe manner when needed.
-  static base::LazyInstance<base::Lock>::Leaky lock = LAZY_INSTANCE_INITIALIZER;
-
-  if (g_allocator) {
-    base::AutoLock auto_lock(lock.Get());
-
-    // Each call resumes from where it last left off so need persistant
-    // iterator. This class has a constructor so even the definition has
-    // to be protected by the lock in order to be thread-safe.
-    static PersistentMemoryAllocator::Iterator iter;
-    if (iter.is_clear())
-      g_allocator->CreateIterator(&iter);
-
-    while (true) {
-      HistogramBase* histogram = GetNextPersistentHistogram(g_allocator, &iter);
-      if (!histogram)
-        break;
-      StatisticsRecorder::RegisterOrDeleteDuplicate(histogram);
-    }
-  }
-}
-
-}  // namespace base
diff --git a/base/metrics/histogram_persistence.h b/base/metrics/histogram_persistence.h
deleted file mode 100644
index 95f4878..0000000
--- a/base/metrics/histogram_persistence.h
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_METRICS_HISTOGRAM_PERSISTENCE_H_
-#define BASE_METRICS_HISTOGRAM_PERSISTENCE_H_
-
-#include "base/base_export.h"
-#include "base/feature_list.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/metrics/histogram_base.h"
-#include "base/metrics/persistent_memory_allocator.h"
-
-namespace base {
-
-// Feature definition for enabling histogram persistence.
-BASE_EXPORT extern const Feature kPersistentHistogramsFeature;
-
-// Histogram containing creation results. Visible for testing.
-BASE_EXPORT HistogramBase* GetCreateHistogramResultHistogram();
-
-// Access a PersistentMemoryAllocator for storing histograms in space that
-// can be persisted or shared between processes. There is only ever one
-// allocator for all such histograms created by a single process though one
-// process may access the histograms created by other processes if it has a
-// handle on its memory segment. This takes ownership of the object and
-// should not be changed without great care as it is likely that there will
-// be pointers to data held in that space. It should be called as soon as
-// possible during startup to capture as many histograms as possible and
-// while operating single-threaded so there are no race-conditions.
-BASE_EXPORT void SetPersistentHistogramMemoryAllocator(
-    PersistentMemoryAllocator* allocator);
-BASE_EXPORT PersistentMemoryAllocator* GetPersistentHistogramMemoryAllocator();
-
-// This access to the persistent allocator is only for testing; it extracts
-// the current allocator completely. This allows easy creation of histograms
-// within persistent memory segments which can then be extracted and used
-// in other ways.
-BASE_EXPORT PersistentMemoryAllocator*
-ReleasePersistentHistogramMemoryAllocatorForTesting();
-
-// Recreate a Histogram from data held in persistent memory. Though this
-// object will be local to the current process, the sample data will be
-// shared with all other threads referencing it. This method takes a |ref|
-// to the top- level histogram data and the |allocator| on which it is found.
-// This method will return nullptr if any problem is detected with the data.
-// The |allocator| may or may not be the same as the PersistentMemoryAllocator
-// set for general use so that this method can be used to extract Histograms
-// from persistent memory segments other than the default place that this
-// process is creating its own histograms. The caller must take ownership of
-// the returned object and destroy it when no longer needed.
-BASE_EXPORT HistogramBase* GetPersistentHistogram(
-    PersistentMemoryAllocator* allocator,
-    int32_t ref);
-
-// Get the next histogram in persistent data based on iterator. The caller
-// must take ownership of the returned object and destroy it when no longer
-// needed.
-BASE_EXPORT HistogramBase* GetNextPersistentHistogram(
-    PersistentMemoryAllocator* allocator,
-    PersistentMemoryAllocator::Iterator* iter);
-
-// Finalize the creation of the histogram, making it available to other
-// processes if it is the registered instance.
-void FinalizePersistentHistogram(PersistentMemoryAllocator::Reference ref,
-                                 bool register);
-
-// Allocate a new persistent histogram. This does *not* make the object
-// iterable in the allocator; call MakeIterable(ref) directly if that is
-// desired.
-BASE_EXPORT HistogramBase* AllocatePersistentHistogram(
-    PersistentMemoryAllocator* allocator,
-    HistogramType histogram_type,
-    const std::string& name,
-    int minimum,
-    int maximum,
-    const BucketRanges* bucket_ranges,
-    int32_t flags,
-    PersistentMemoryAllocator::Reference* ref_ptr);
-
-// Import new histograms from attached PersistentMemoryAllocator. It's
-// possible for other processes to create histograms in the attached memory
-// segment; this adds those to the internal list of known histograms to
-// avoid creating duplicates that would have to merged during reporting.
-// Every call to this method resumes from the last entry it saw so it costs
-// nothing if nothing new has been added.
-void ImportPersistentHistograms();
-
-}  // namespace base
-
-#endif  // BASE_METRICS_HISTOGRAM_PERSISTENCE_H_
diff --git a/base/metrics/histogram_samples.h b/base/metrics/histogram_samples.h
index 29fbe17..30bff84 100644
--- a/base/metrics/histogram_samples.h
+++ b/base/metrics/histogram_samples.h
@@ -22,7 +22,7 @@
 // HistogramSamples is a container storing all samples of a histogram. All
 // elements must be of a fixed width to ensure 32/64-bit interoperability.
 // If this structure changes, bump the version number for kTypeIdHistogram
-// in histogram_persistence.cc.
+// in persistent_histogram_allocator.cc.
 class BASE_EXPORT HistogramSamples {
  public:
   struct Metadata {
diff --git a/base/metrics/histogram_unittest.cc b/base/metrics/histogram_unittest.cc
index beb6a71..f621ec5 100644
--- a/base/metrics/histogram_unittest.cc
+++ b/base/metrics/histogram_unittest.cc
@@ -16,7 +16,7 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/metrics/bucket_ranges.h"
 #include "base/metrics/histogram_macros.h"
-#include "base/metrics/histogram_persistence.h"
+#include "base/metrics/persistent_histogram_allocator.h"
 #include "base/metrics/persistent_memory_allocator.h"
 #include "base/metrics/sample_vector.h"
 #include "base/metrics/statistics_recorder.h"
@@ -41,7 +41,7 @@
     // registered).
     InitializeStatisticsRecorder();
     if (use_persistent_histogram_allocator_)
-      CreatePersistentMemoryAllocator();
+      CreatePersistentHistogramAllocator();
   }
 
   void TearDown() override {
@@ -50,7 +50,7 @@
       ASSERT_FALSE(allocator_->IsCorrupt());
     }
     UninitializeStatisticsRecorder();
-    DestroyPersistentMemoryAllocator();
+    DestroyPersistentHistogramAllocator();
   }
 
   void InitializeStatisticsRecorder() {
@@ -63,27 +63,27 @@
     statistics_recorder_ = NULL;
   }
 
-  void CreatePersistentMemoryAllocator() {
+  void CreatePersistentHistogramAllocator() {
     // By getting the results-histogram before any persistent allocator
     // is attached, that histogram is guaranteed not to be stored in
     // any persistent memory segment (which simplifies some tests).
-    GetCreateHistogramResultHistogram();
+    PersistentHistogramAllocator::GetCreateHistogramResultHistogram();
 
     if (!allocator_memory_)
       allocator_memory_.reset(new char[kAllocatorMemorySize]);
 
-    delete ReleasePersistentHistogramMemoryAllocatorForTesting();
+    PersistentHistogramAllocator::ReleaseGlobalAllocatorForTesting();
     memset(allocator_memory_.get(), 0, kAllocatorMemorySize);
-    SetPersistentHistogramMemoryAllocator(
-        new PersistentMemoryAllocator(
-            allocator_memory_.get(), kAllocatorMemorySize, 0,
-            0, "HistogramAllocatorTest", false));
-    allocator_ = GetPersistentHistogramMemoryAllocator();
+    PersistentHistogramAllocator::CreateGlobalAllocatorOnPersistentMemory(
+        allocator_memory_.get(), kAllocatorMemorySize, 0, 0,
+        "HistogramAllocatorTest");
+    allocator_ =
+        PersistentHistogramAllocator::GetGlobalAllocator()->memory_allocator();
   }
 
-  void DestroyPersistentMemoryAllocator() {
+  void DestroyPersistentHistogramAllocator() {
     allocator_ = nullptr;
-    delete ReleasePersistentHistogramMemoryAllocatorForTesting();
+    PersistentHistogramAllocator::ReleaseGlobalAllocatorForTesting();
   }
 
   const bool use_persistent_histogram_allocator_;
@@ -97,8 +97,7 @@
 };
 
 // Run all HistogramTest cases with both heap and persistent memory.
-INSTANTIATE_TEST_CASE_P(HeapAndPersistent, HistogramTest,
-                        testing::Bool());
+INSTANTIATE_TEST_CASE_P(HeapAndPersistent, HistogramTest, testing::Bool());
 
 
 // Check for basic syntax and use.
@@ -126,94 +125,6 @@
   LOCAL_HISTOGRAM_ENUMERATION("Test6Histogram", 129, 130);
 }
 
-// Check for basic syntax and use with persistent allocator.
-TEST_P(HistogramTest, PersistentTest) {
-  if (!use_persistent_histogram_allocator_)
-    return;
-
-  PersistentMemoryAllocator::MemoryInfo meminfo0;
-  allocator_->GetMemoryInfo(&meminfo0);
-
-  // Try basic construction
-  HistogramBase* histogram = Histogram::FactoryGet(
-      "TestHistogram", 1, 1000, 10,
-      HistogramBase::kIsPersistent);
-  EXPECT_TRUE(histogram);
-  histogram->CheckName("TestHistogram");
-  PersistentMemoryAllocator::MemoryInfo meminfo1;
-  allocator_->GetMemoryInfo(&meminfo1);
-  EXPECT_GT(meminfo0.free, meminfo1.free);
-
-  HistogramBase* linear_histogram = LinearHistogram::FactoryGet(
-      "TestLinearHistogram", 1, 1000, 10,
-      HistogramBase::kIsPersistent);
-  EXPECT_TRUE(linear_histogram);
-  linear_histogram->CheckName("TestLinearHistogram");
-  PersistentMemoryAllocator::MemoryInfo meminfo2;
-  allocator_->GetMemoryInfo(&meminfo2);
-  EXPECT_GT(meminfo1.free, meminfo2.free);
-
-  HistogramBase* boolean_histogram = BooleanHistogram::FactoryGet(
-      "TestBooleanHistogram", HistogramBase::kIsPersistent);
-  EXPECT_TRUE(boolean_histogram);
-  boolean_histogram->CheckName("TestBooleanHistogram");
-  PersistentMemoryAllocator::MemoryInfo meminfo3;
-  allocator_->GetMemoryInfo(&meminfo3);
-  EXPECT_GT(meminfo2.free, meminfo3.free);
-
-  std::vector<int> custom_ranges;
-  custom_ranges.push_back(1);
-  custom_ranges.push_back(5);
-  HistogramBase* custom_histogram = CustomHistogram::FactoryGet(
-      "TestCustomHistogram", custom_ranges,
-      HistogramBase::kIsPersistent);
-  EXPECT_TRUE(custom_histogram);
-  custom_histogram->CheckName("TestCustomHistogram");
-  PersistentMemoryAllocator::MemoryInfo meminfo4;
-  allocator_->GetMemoryInfo(&meminfo4);
-  EXPECT_GT(meminfo3.free, meminfo4.free);
-
-  PersistentMemoryAllocator::Iterator iter;
-  uint32_t type;
-  allocator_->CreateIterator(&iter);
-  EXPECT_NE(0U, allocator_->GetNextIterable(&iter, &type));  // Histogram
-  EXPECT_NE(0U, allocator_->GetNextIterable(&iter, &type));  // LinearHistogram
-  EXPECT_NE(0U, allocator_->GetNextIterable(&iter, &type));  // BooleanHistogram
-  EXPECT_NE(0U, allocator_->GetNextIterable(&iter, &type));  // CustomHistogram
-  EXPECT_EQ(0U, allocator_->GetNextIterable(&iter, &type));
-
-  // Create a second allocator and have it access the memory of the first.
-  scoped_ptr<HistogramBase> recovered;
-  PersistentMemoryAllocator recovery(
-      allocator_memory_.get(), kAllocatorMemorySize, 0,
-      0, std::string(), false);
-  recovery.CreateIterator(&iter);
-
-  recovered.reset(GetNextPersistentHistogram(&recovery, &iter));
-  ASSERT_TRUE(recovered);
-  recovered->CheckName("TestHistogram");
-
-  recovered.reset(GetNextPersistentHistogram(&recovery, &iter));
-  ASSERT_TRUE(recovered);
-  recovered->CheckName("TestLinearHistogram");
-
-  recovered.reset(GetNextPersistentHistogram(&recovery, &iter));
-  ASSERT_TRUE(recovered);
-  recovered->CheckName("TestBooleanHistogram");
-
-  recovered.reset(GetNextPersistentHistogram(&recovery, &iter));
-  ASSERT_TRUE(recovered);
-  recovered->CheckName("TestCustomHistogram");
-
-  recovered.reset(GetNextPersistentHistogram(&recovery, &iter));
-  EXPECT_FALSE(recovered);
-
-  // Use standard macros (but with fixed samples)
-  LOCAL_HISTOGRAM_TIMES("Test2Histogram", TimeDelta::FromDays(1));
-  LOCAL_HISTOGRAM_COUNTS("Test3Histogram", 30);
-  LOCAL_HISTOGRAM_ENUMERATION("Test6Histogram", 129, 130);
-}
-
 // Check that the macro correctly matches histograms by name and records their
 // data together.
 TEST_P(HistogramTest, NameMatchTest) {
diff --git a/base/metrics/persistent_histogram_allocator.cc b/base/metrics/persistent_histogram_allocator.cc
new file mode 100644
index 0000000..1929060
--- /dev/null
+++ b/base/metrics/persistent_histogram_allocator.cc
@@ -0,0 +1,554 @@
+// 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 "base/metrics/persistent_histogram_allocator.h"
+
+#include "base/lazy_instance.h"
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/metrics/histogram.h"
+#include "base/metrics/histogram_base.h"
+#include "base/metrics/histogram_samples.h"
+#include "base/metrics/statistics_recorder.h"
+#include "base/synchronization/lock.h"
+
+// TODO(bcwhite): Order these methods to match the header file. The current
+// order is only temporary in order to aid review of the transition from
+// a non-class implementation.
+
+namespace base {
+
+namespace {
+
+// Name of histogram for storing results of local operations.
+const char kResultHistogram[] = "UMA.CreatePersistentHistogram.Result";
+
+// Type identifiers used when storing in persistent memory so they can be
+// identified during extraction; the first 4 bytes of the SHA1 of the name
+// is used as a unique integer. A "version number" is added to the base
+// so that, if the structure of that object changes, stored older versions
+// will be safely ignored.
+enum : uint32_t {
+  kTypeIdHistogram   = 0xF1645910 + 2,  // SHA1(Histogram)   v2
+  kTypeIdRangesArray = 0xBCEA225A + 1,  // SHA1(RangesArray) v1
+  kTypeIdCountsArray = 0x53215530 + 1,  // SHA1(CountsArray) v1
+};
+
+// The current globally-active persistent allocator for all new histograms.
+// The object held here will obviously not be destructed at process exit
+// but that's best since PersistentMemoryAllocator objects (that underlie
+// PersistentHistogramAllocator objects) are explicitly forbidden from doing
+// anything essential at exit anyway due to the fact that they depend on data
+// managed elsewhere and which could be destructed first.
+PersistentHistogramAllocator* g_allocator;
+
+// Take an array of range boundaries and create a proper BucketRanges object
+// which is returned to the caller. A return of nullptr indicates that the
+// passed boundaries are invalid.
+scoped_ptr<BucketRanges> CreateRangesFromData(
+    HistogramBase::Sample* ranges_data,
+    uint32_t ranges_checksum,
+    size_t count) {
+  // To avoid racy destruction at shutdown, the following may be leaked.
+  scoped_ptr<BucketRanges> ranges(new BucketRanges(count));
+  DCHECK_EQ(count, ranges->size());
+  for (size_t i = 0; i < count; ++i) {
+    if (i > 0 && ranges_data[i] <= ranges_data[i - 1])
+      return nullptr;
+    ranges->set_range(i, ranges_data[i]);
+  }
+
+  ranges->ResetChecksum();
+  if (ranges->checksum() != ranges_checksum)
+    return nullptr;
+
+  return ranges;
+}
+
+// Calculate the number of bytes required to store all of a histogram's
+// "counts". This will return zero (0) if |bucket_count| is not valid.
+size_t CalculateRequiredCountsBytes(size_t bucket_count) {
+  // 2 because each "sample count" also requires a backup "logged count"
+  // used for calculating the delta during snapshot operations.
+  const unsigned kBytesPerBucket = 2 * sizeof(HistogramBase::AtomicCount);
+
+  // If the |bucket_count| is such that it would overflow the return type,
+  // perhaps as the result of a malicious actor, then return zero to
+  // indicate the problem to the caller.
+  if (bucket_count > std::numeric_limits<uint32_t>::max() / kBytesPerBucket)
+    return 0;
+
+  return bucket_count * kBytesPerBucket;
+}
+
+}  // namespace
+
+const Feature kPersistentHistogramsFeature{
+  "PersistentHistograms", FEATURE_DISABLED_BY_DEFAULT
+};
+
+// This data will be held in persistent memory in order for processes to
+// locate and use histograms created elsewhere.
+struct PersistentHistogramAllocator::PersistentHistogramData {
+  int32_t histogram_type;
+  int32_t flags;
+  int32_t minimum;
+  int32_t maximum;
+  uint32_t bucket_count;
+  PersistentMemoryAllocator::Reference ranges_ref;
+  uint32_t ranges_checksum;
+  PersistentMemoryAllocator::Reference counts_ref;
+  HistogramSamples::Metadata samples_metadata;
+  HistogramSamples::Metadata logged_metadata;
+
+  // Space for the histogram name will be added during the actual allocation
+  // request. This must be the last field of the structure. A zero-size array
+  // or a "flexible" array would be preferred but is not (yet) valid C++.
+  char name[1];
+};
+
+PersistentHistogramAllocator::PersistentHistogramAllocator(
+    scoped_ptr<PersistentMemoryAllocator> memory)
+    : memory_allocator_(std::move(memory)) {}
+
+PersistentHistogramAllocator::~PersistentHistogramAllocator() {}
+
+void PersistentHistogramAllocator::CreateIterator(Iterator* iter) {
+  memory_allocator_->CreateIterator(&iter->memory_iter);
+}
+
+void PersistentHistogramAllocator::CreateTrackingHistograms(StringPiece name) {
+  memory_allocator_->CreateTrackingHistograms(name);
+}
+
+void PersistentHistogramAllocator::UpdateTrackingHistograms() {
+  memory_allocator_->UpdateTrackingHistograms();
+}
+
+// static
+HistogramBase*
+PersistentHistogramAllocator::GetCreateHistogramResultHistogram() {
+  // Get the histogram in which create-results are stored. This is copied
+  // almost exactly from the STATIC_HISTOGRAM_POINTER_BLOCK macro but with
+  // added code to prevent recursion (a likely occurance because the creation
+  // of a new a histogram can end up calling this.)
+  static base::subtle::AtomicWord atomic_histogram_pointer = 0;
+  HistogramBase* histogram_pointer =
+      reinterpret_cast<HistogramBase*>(
+          base::subtle::Acquire_Load(&atomic_histogram_pointer));
+  if (!histogram_pointer) {
+    // It's possible for multiple threads to make it here in parallel but
+    // they'll always return the same result as there is a mutex in the Get.
+    // The purpose of the "initialized" variable is just to ensure that
+    // the same thread doesn't recurse which is also why it doesn't have
+    // to be atomic.
+    static bool initialized = false;
+    if (!initialized) {
+      initialized = true;
+      if (g_allocator) {
+        DLOG(WARNING) << "Creating the results-histogram inside persistent"
+                      << " memory can cause future allocations to crash if"
+                      << " that memory is ever released (for testing).";
+      }
+
+      histogram_pointer = LinearHistogram::FactoryGet(
+          kResultHistogram, 1, CREATE_HISTOGRAM_MAX, CREATE_HISTOGRAM_MAX + 1,
+          HistogramBase::kUmaTargetedHistogramFlag);
+      base::subtle::Release_Store(
+          &atomic_histogram_pointer,
+          reinterpret_cast<base::subtle::AtomicWord>(histogram_pointer));
+    }
+  }
+  return histogram_pointer;
+}
+
+// static
+void PersistentHistogramAllocator::RecordCreateHistogramResult(
+    CreateHistogramResultType result) {
+  HistogramBase* result_histogram = GetCreateHistogramResultHistogram();
+  if (result_histogram)
+    result_histogram->Add(result);
+}
+
+// static
+void PersistentHistogramAllocator::SetGlobalAllocator(
+    scoped_ptr<PersistentHistogramAllocator> allocator) {
+  // Releasing or changing an allocator is extremely dangerous because it
+  // likely has histograms stored within it. If the backing memory is also
+  // also released, future accesses to those histograms will seg-fault.
+  CHECK(!g_allocator);
+  g_allocator = allocator.release();
+}
+
+// static
+PersistentHistogramAllocator*
+PersistentHistogramAllocator::GetGlobalAllocator() {
+  return g_allocator;
+}
+
+// static
+scoped_ptr<PersistentHistogramAllocator>
+PersistentHistogramAllocator::ReleaseGlobalAllocatorForTesting() {
+  PersistentHistogramAllocator* histogram_allocator = g_allocator;
+  if (!histogram_allocator)
+    return nullptr;
+  PersistentMemoryAllocator* memory_allocator =
+      histogram_allocator->memory_allocator();
+
+  // Before releasing the memory, it's necessary to have the Statistics-
+  // Recorder forget about the histograms contained therein; otherwise,
+  // some operations will try to access them and the released memory.
+  PersistentMemoryAllocator::Iterator iter;
+  PersistentMemoryAllocator::Reference ref;
+  uint32_t type_id;
+  memory_allocator->CreateIterator(&iter);
+  while ((ref = memory_allocator->GetNextIterable(&iter, &type_id)) != 0) {
+    if (type_id == kTypeIdHistogram) {
+      PersistentHistogramData* histogram_data =
+          memory_allocator->GetAsObject<PersistentHistogramData>(
+              ref, kTypeIdHistogram);
+      DCHECK(histogram_data);
+      StatisticsRecorder::ForgetHistogramForTesting(histogram_data->name);
+
+      // If a test breaks here then a memory region containing a histogram
+      // actively used by this code is being released back to the test.
+      // If that memory segment were to be deleted, future calls to create
+      // persistent histograms would crash. To avoid this, have the test call
+      // the method GetCreateHistogramResultHistogram() *before* setting
+      // the (temporary) memory allocator via SetGlobalAllocator() so that
+      // histogram is instead allocated from the process heap.
+      DCHECK_NE(kResultHistogram, histogram_data->name);
+    }
+  }
+
+  g_allocator = nullptr;
+  return make_scoped_ptr(histogram_allocator);
+};
+
+// static
+void PersistentHistogramAllocator::CreateGlobalAllocatorOnPersistentMemory(
+    void* base,
+    size_t size,
+    size_t page_size,
+    uint64_t id,
+    StringPiece name) {
+  SetGlobalAllocator(make_scoped_ptr(new PersistentHistogramAllocator(
+      make_scoped_ptr(new PersistentMemoryAllocator(
+          base, size, page_size, id, name, false)))));
+}
+
+// static
+void PersistentHistogramAllocator::CreateGlobalAllocatorOnLocalMemory(
+    size_t size,
+    uint64_t id,
+    StringPiece name) {
+  SetGlobalAllocator(make_scoped_ptr(new PersistentHistogramAllocator(
+      make_scoped_ptr(new LocalPersistentMemoryAllocator(size, id, name)))));
+}
+
+// static
+void PersistentHistogramAllocator::CreateGlobalAllocatorOnSharedMemory(
+    size_t size,
+    const SharedMemoryHandle& handle) {
+  scoped_ptr<SharedMemory> shm(new SharedMemory(handle, /*readonly=*/false));
+  if (!shm->Map(size)) {
+    NOTREACHED();
+    return;
+  }
+
+  SetGlobalAllocator(make_scoped_ptr(new PersistentHistogramAllocator(
+      make_scoped_ptr(new SharedPersistentMemoryAllocator(
+          std::move(shm), 0, StringPiece(), /*readonly=*/false)))));
+}
+
+// static
+scoped_ptr<HistogramBase> PersistentHistogramAllocator::CreateHistogram(
+    PersistentHistogramData* histogram_data_ptr) {
+  if (!histogram_data_ptr) {
+    RecordCreateHistogramResult(CREATE_HISTOGRAM_INVALID_METADATA_POINTER);
+    NOTREACHED();
+    return nullptr;
+  }
+
+  // Copy the histogram_data to local storage because anything in persistent
+  // memory cannot be trusted as it could be changed at any moment by a
+  // malicious actor that shares access. The contents of histogram_data are
+  // validated below; the local copy is to ensure that the contents cannot
+  // be externally changed between validation and use.
+  PersistentHistogramData histogram_data = *histogram_data_ptr;
+
+  HistogramBase::Sample* ranges_data =
+      memory_allocator_->GetAsObject<HistogramBase::Sample>(
+          histogram_data.ranges_ref, kTypeIdRangesArray);
+
+  const uint32_t max_buckets =
+      std::numeric_limits<uint32_t>::max() / sizeof(HistogramBase::Sample);
+  size_t required_bytes =
+      (histogram_data.bucket_count + 1) * sizeof(HistogramBase::Sample);
+  size_t allocated_bytes =
+      memory_allocator_->GetAllocSize(histogram_data.ranges_ref);
+  if (!ranges_data || histogram_data.bucket_count < 2 ||
+      histogram_data.bucket_count >= max_buckets ||
+      allocated_bytes < required_bytes) {
+    RecordCreateHistogramResult(CREATE_HISTOGRAM_INVALID_RANGES_ARRAY);
+    NOTREACHED();
+    return nullptr;
+  }
+
+  scoped_ptr<const BucketRanges> created_ranges =
+      CreateRangesFromData(ranges_data, histogram_data.ranges_checksum,
+                           histogram_data.bucket_count + 1);
+  if (!created_ranges) {
+    RecordCreateHistogramResult(CREATE_HISTOGRAM_INVALID_RANGES_ARRAY);
+    NOTREACHED();
+    return nullptr;
+  }
+  const BucketRanges* ranges =
+      StatisticsRecorder::RegisterOrDeleteDuplicateRanges(
+          created_ranges.release());
+
+  HistogramBase::AtomicCount* counts_data =
+      memory_allocator_->GetAsObject<HistogramBase::AtomicCount>(
+          histogram_data.counts_ref, kTypeIdCountsArray);
+  size_t counts_bytes =
+      CalculateRequiredCountsBytes(histogram_data.bucket_count);
+  if (!counts_data || !counts_bytes ||
+      memory_allocator_->GetAllocSize(histogram_data.counts_ref) <
+          counts_bytes) {
+    RecordCreateHistogramResult(CREATE_HISTOGRAM_INVALID_COUNTS_ARRAY);
+    NOTREACHED();
+    return nullptr;
+  }
+
+  // After the main "counts" array is a second array using for storing what
+  // was previously logged. This is used to calculate the "delta" during
+  // snapshot operations.
+  HistogramBase::AtomicCount* logged_data =
+      counts_data + histogram_data.bucket_count;
+
+  std::string name(histogram_data_ptr->name);
+  scoped_ptr<HistogramBase> histogram;
+  switch (histogram_data.histogram_type) {
+    case HISTOGRAM:
+      histogram = Histogram::PersistentCreate(
+          name, histogram_data.minimum, histogram_data.maximum, ranges,
+          counts_data, logged_data, histogram_data.bucket_count,
+          &histogram_data_ptr->samples_metadata,
+          &histogram_data_ptr->logged_metadata);
+      DCHECK(histogram);
+      break;
+    case LINEAR_HISTOGRAM:
+      histogram = LinearHistogram::PersistentCreate(
+          name, histogram_data.minimum, histogram_data.maximum, ranges,
+          counts_data, logged_data, histogram_data.bucket_count,
+          &histogram_data_ptr->samples_metadata,
+          &histogram_data_ptr->logged_metadata);
+      DCHECK(histogram);
+      break;
+    case BOOLEAN_HISTOGRAM:
+      histogram = BooleanHistogram::PersistentCreate(
+          name, ranges, counts_data, logged_data,
+          &histogram_data_ptr->samples_metadata,
+          &histogram_data_ptr->logged_metadata);
+      DCHECK(histogram);
+      break;
+    case CUSTOM_HISTOGRAM:
+      histogram = CustomHistogram::PersistentCreate(
+          name, ranges, counts_data, logged_data, histogram_data.bucket_count,
+          &histogram_data_ptr->samples_metadata,
+          &histogram_data_ptr->logged_metadata);
+      DCHECK(histogram);
+      break;
+    default:
+      NOTREACHED();
+  }
+
+  if (histogram) {
+    DCHECK_EQ(histogram_data.histogram_type, histogram->GetHistogramType());
+    histogram->SetFlags(histogram_data.flags);
+    RecordCreateHistogramResult(CREATE_HISTOGRAM_SUCCESS);
+  } else {
+    RecordCreateHistogramResult(CREATE_HISTOGRAM_UNKNOWN_TYPE);
+  }
+
+  return histogram;
+}
+
+scoped_ptr<HistogramBase> PersistentHistogramAllocator::GetHistogram(
+    Reference ref) {
+  // Unfortunately, the histogram "pickle" methods cannot be used as part of
+  // the persistance because the deserialization methods always create local
+  // count data (while these must reference the persistent counts) and always
+  // add it to the local list of known histograms (while these may be simple
+  // references to histograms in other processes).
+  PersistentHistogramData* histogram_data =
+      memory_allocator_->GetAsObject<PersistentHistogramData>(
+          ref, kTypeIdHistogram);
+  size_t length = memory_allocator_->GetAllocSize(ref);
+  if (!histogram_data ||
+      reinterpret_cast<char*>(histogram_data)[length - 1] != '\0') {
+    RecordCreateHistogramResult(CREATE_HISTOGRAM_INVALID_METADATA);
+    NOTREACHED();
+    return nullptr;
+  }
+  return CreateHistogram(histogram_data);
+}
+
+scoped_ptr<HistogramBase>
+PersistentHistogramAllocator::GetNextHistogramWithIgnore(Iterator* iter,
+                                                         Reference ignore) {
+  PersistentMemoryAllocator::Reference ref;
+  uint32_t type_id;
+  while ((ref = memory_allocator_->GetNextIterable(&iter->memory_iter,
+                                                   &type_id)) != 0) {
+    if (ref == ignore)
+      continue;
+    if (type_id == kTypeIdHistogram)
+      return GetHistogram(ref);
+  }
+  return nullptr;
+}
+
+void PersistentHistogramAllocator::FinalizeHistogram(Reference ref,
+                                                     bool registered) {
+  // If the created persistent histogram was registered then it needs to
+  // be marked as "iterable" in order to be found by other processes.
+  if (registered)
+    memory_allocator_->MakeIterable(ref);
+  // If it wasn't registered then a race condition must have caused
+  // two to be created. The allocator does not support releasing the
+  // acquired memory so just change the type to be empty.
+  else
+    memory_allocator_->SetType(ref, 0);
+}
+
+scoped_ptr<HistogramBase> PersistentHistogramAllocator::AllocateHistogram(
+    HistogramType histogram_type,
+    const std::string& name,
+    int minimum,
+    int maximum,
+    const BucketRanges* bucket_ranges,
+    int32_t flags,
+    Reference* ref_ptr) {
+  // If the allocator is corrupt, don't waste time trying anything else.
+  // This also allows differentiating on the dashboard between allocations
+  // failed due to a corrupt allocator and the number of process instances
+  // with one, the latter being idicated by "newly corrupt", below.
+  if (memory_allocator_->IsCorrupt()) {
+    RecordCreateHistogramResult(CREATE_HISTOGRAM_ALLOCATOR_CORRUPT);
+    return nullptr;
+  }
+
+  // If CalculateRequiredCountsBytes() returns zero then the bucket_count
+  // was not valid.
+  size_t bucket_count = bucket_ranges->bucket_count();
+  size_t counts_bytes = CalculateRequiredCountsBytes(bucket_count);
+  if (!counts_bytes) {
+    NOTREACHED();
+    return nullptr;
+  }
+
+  size_t ranges_bytes = (bucket_count + 1) * sizeof(HistogramBase::Sample);
+  PersistentMemoryAllocator::Reference ranges_ref =
+      memory_allocator_->Allocate(ranges_bytes, kTypeIdRangesArray);
+  PersistentMemoryAllocator::Reference counts_ref =
+      memory_allocator_->Allocate(counts_bytes, kTypeIdCountsArray);
+  PersistentMemoryAllocator::Reference histogram_ref =
+      memory_allocator_->Allocate(
+          offsetof(PersistentHistogramData, name) + name.length() + 1,
+          kTypeIdHistogram);
+  HistogramBase::Sample* ranges_data =
+      memory_allocator_->GetAsObject<HistogramBase::Sample>(ranges_ref,
+                                                            kTypeIdRangesArray);
+  PersistentHistogramData* histogram_data =
+      memory_allocator_->GetAsObject<PersistentHistogramData>(histogram_ref,
+                                                              kTypeIdHistogram);
+
+  // Only continue here if all allocations were successful. If they weren't,
+  // there is no way to free the space but that's not really a problem since
+  // the allocations only fail because the space is full or corrupt and so
+  // any future attempts will also fail.
+  if (counts_ref && ranges_data && histogram_data) {
+    strcpy(histogram_data->name, name.c_str());
+    for (size_t i = 0; i < bucket_ranges->size(); ++i)
+      ranges_data[i] = bucket_ranges->range(i);
+
+    histogram_data->histogram_type = histogram_type;
+    histogram_data->flags = flags;
+    histogram_data->minimum = minimum;
+    histogram_data->maximum = maximum;
+    histogram_data->bucket_count = static_cast<uint32_t>(bucket_count);
+    histogram_data->ranges_ref = ranges_ref;
+    histogram_data->ranges_checksum = bucket_ranges->checksum();
+    histogram_data->counts_ref = counts_ref;
+
+    // Create the histogram using resources in persistent memory. This ends up
+    // resolving the "ref" values stored in histogram_data instad of just
+    // using what is already known above but avoids duplicating the switch
+    // statement here and serves as a double-check that everything is
+    // correct before commiting the new histogram to persistent space.
+    scoped_ptr<HistogramBase> histogram = CreateHistogram(histogram_data);
+    DCHECK(histogram);
+    if (ref_ptr != nullptr)
+      *ref_ptr = histogram_ref;
+
+    // By storing the reference within the allocator to this histogram, the
+    // next import (which will happen before the next histogram creation)
+    // will know to skip it. See also the comment in ImportGlobalHistograms().
+    subtle::NoBarrier_Store(&last_created_, histogram_ref);
+    return histogram;
+  }
+
+  CreateHistogramResultType result;
+  if (memory_allocator_->IsCorrupt()) {
+    RecordCreateHistogramResult(CREATE_HISTOGRAM_ALLOCATOR_NEWLY_CORRUPT);
+    result = CREATE_HISTOGRAM_ALLOCATOR_CORRUPT;
+  } else if (memory_allocator_->IsFull()) {
+    result = CREATE_HISTOGRAM_ALLOCATOR_FULL;
+  } else {
+    result = CREATE_HISTOGRAM_ALLOCATOR_ERROR;
+  }
+  RecordCreateHistogramResult(result);
+  NOTREACHED() << "error=" << result;
+
+  return nullptr;
+}
+
+// static
+void PersistentHistogramAllocator::ImportGlobalHistograms() {
+  // The lock protects against concurrent access to the iterator and is created
+  // in a thread-safe manner when needed.
+  static base::LazyInstance<base::Lock>::Leaky lock = LAZY_INSTANCE_INITIALIZER;
+
+  if (g_allocator) {
+    // TODO(bcwhite): Investigate a lock-free, thread-safe iterator.
+    base::AutoLock auto_lock(lock.Get());
+
+    // Each call resumes from where it last left off so a persistant iterator
+    // is needed. This class has a constructor so even the definition has to
+    // be protected by the lock in order to be thread-safe.
+    static Iterator iter;
+    if (iter.is_clear())
+      g_allocator->CreateIterator(&iter);
+
+    // Skip the import if it's the histogram that was last created. Should a
+    // race condition cause the "last created" to be overwritten before it
+    // is recognized here then the histogram will be created and be ignored
+    // when it is detected as a duplicate by the statistics-recorder. This
+    // simple check reduces the time of creating persistent histograms by
+    // about 40%.
+    Reference last_created =
+        subtle::NoBarrier_Load(&g_allocator->last_created_);
+
+    while (true) {
+      scoped_ptr<HistogramBase> histogram =
+          g_allocator->GetNextHistogramWithIgnore(&iter, last_created);
+      if (!histogram)
+        break;
+      StatisticsRecorder::RegisterOrDeleteDuplicate(histogram.release());
+    }
+  }
+}
+
+}  // namespace base
diff --git a/base/metrics/persistent_histogram_allocator.h b/base/metrics/persistent_histogram_allocator.h
new file mode 100644
index 0000000..cc8d023
--- /dev/null
+++ b/base/metrics/persistent_histogram_allocator.h
@@ -0,0 +1,212 @@
+// 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 BASE_METRICS_HISTOGRAM_PERSISTENCE_H_
+#define BASE_METRICS_HISTOGRAM_PERSISTENCE_H_
+
+#include "base/atomicops.h"
+#include "base/base_export.h"
+#include "base/feature_list.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/shared_memory.h"
+#include "base/metrics/histogram_base.h"
+#include "base/metrics/persistent_memory_allocator.h"
+#include "base/strings/string_piece.h"
+
+namespace base {
+
+// Feature definition for enabling histogram persistence.
+BASE_EXPORT extern const Feature kPersistentHistogramsFeature;
+
+// This class manages histograms created within a PersistentMemoryAllocator.
+class BASE_EXPORT PersistentHistogramAllocator {
+ public:
+  // This iterator is used for fetching persistent histograms from an allocator.
+  class Iterator {
+   public:
+    bool is_clear() { return memory_iter.is_clear(); }
+
+   private:
+    friend class PersistentHistogramAllocator;
+
+    // The iterator used for stepping through persistent memory iterables.
+    PersistentMemoryAllocator::Iterator memory_iter;
+  };
+
+  using Reference = PersistentMemoryAllocator::Reference;
+
+  // A PersistentHistogramAllocator is constructed from a PersistentMemory-
+  // Allocator object of which it takes ownership.
+  PersistentHistogramAllocator(scoped_ptr<PersistentMemoryAllocator> memory);
+  ~PersistentHistogramAllocator();
+
+  // Direct access to underlying memory allocator. If the segment is shared
+  // across threads or processes, reading data through these values does
+  // not guarantee consistency. Use with care. Do not write.
+  PersistentMemoryAllocator* memory_allocator() {
+    return memory_allocator_.get();
+  }
+
+  // Implement the "metadata" API of a PersistentMemoryAllocator, forwarding
+  // those requests to the real one.
+  uint64_t Id() const { return memory_allocator_->Id(); }
+  const char* Name() const { return memory_allocator_->Name(); }
+  const void* data() const { return memory_allocator_->data(); }
+  size_t length() const { return memory_allocator_->length(); }
+  size_t used() const { return memory_allocator_->used(); }
+
+  // Recreate a Histogram from data held in persistent memory. Though this
+  // object will be local to the current process, the sample data will be
+  // shared with all other threads referencing it. This method takes a |ref|
+  // to where the top-level histogram data may be found in this allocator.
+  // This method will return null if any problem is detected with the data.
+  scoped_ptr<HistogramBase> GetHistogram(Reference ref);
+
+  // Get the next histogram in persistent data based on iterator.
+  scoped_ptr<HistogramBase> GetNextHistogram(Iterator* iter) {
+    return GetNextHistogramWithIgnore(iter, 0);
+  }
+
+  // Create an iterator for going through all histograms in an allocator.
+  void CreateIterator(Iterator* iter);
+
+  // Allocate a new persistent histogram. The returned histogram will not
+  // be able to be located by other allocators until it is "finalized".
+  scoped_ptr<HistogramBase> AllocateHistogram(
+      HistogramType histogram_type,
+      const std::string& name,
+      int minimum,
+      int maximum,
+      const BucketRanges* bucket_ranges,
+      int32_t flags,
+      Reference* ref_ptr);
+
+  // Finalize the creation of the histogram, making it available to other
+  // processes if |registered| (as in: added to the StatisticsRecorder) is
+  // True, forgetting it otherwise.
+  void FinalizeHistogram(Reference ref, bool registered);
+
+  // Create internal histograms for tracking memory use and allocation sizes
+  // for allocator of |name| (which can simply be the result of Name()). This
+  // is done seperately from construction for situations such as when the
+  // histograms will be backed by memory provided by this very allocator.
+  //
+  // IMPORTANT: Callers must update tools/metrics/histograms/histograms.xml
+  // with the following histograms:
+  //    UMA.PersistentAllocator.name.Allocs
+  //    UMA.PersistentAllocator.name.UsedPct
+  void CreateTrackingHistograms(StringPiece name);
+  void UpdateTrackingHistograms();
+
+  // Manage a PersistentHistogramAllocator for globally storing histograms in
+  // a space that can be persisted or shared between processes. There is only
+  // ever one allocator for all such histograms created by a single process.
+  // This takes ownership of the object and should be called as soon as
+  // possible during startup to capture as many histograms as possible and
+  // while operating single-threaded so there are no race-conditions.
+  static void SetGlobalAllocator(
+      scoped_ptr<PersistentHistogramAllocator> allocator);
+  static PersistentHistogramAllocator* GetGlobalAllocator();
+
+  // This access to the persistent allocator is only for testing; it extracts
+  // the current allocator completely. This allows easy creation of histograms
+  // within persistent memory segments which can then be extracted and used
+  // in other ways.
+  static scoped_ptr<PersistentHistogramAllocator>
+  ReleaseGlobalAllocatorForTesting();
+
+  // These helper methods perform SetGlobalAllocator() calls with allocators
+  // of the specified type and parameters.
+  static void CreateGlobalAllocatorOnPersistentMemory(
+      void* base,
+      size_t size,
+      size_t page_size,
+      uint64_t id,
+      StringPiece name);
+  static void CreateGlobalAllocatorOnLocalMemory(
+      size_t size,
+      uint64_t id,
+      StringPiece name);
+  static void CreateGlobalAllocatorOnSharedMemory(
+      size_t size,
+      const SharedMemoryHandle& handle);
+
+  // Import new histograms from the global PersistentHistogramAllocator. It's
+  // possible for other processes to create histograms in the active memory
+  // segment; this adds those to the internal list of known histograms to
+  // avoid creating duplicates that would have to be merged during reporting.
+  // Every call to this method resumes from the last entry it saw; it costs
+  // nothing if nothing new has been added.
+  static void ImportGlobalHistograms();
+
+  // Histogram containing creation results. Visible for testing.
+  static HistogramBase* GetCreateHistogramResultHistogram();
+
+ private:
+  // Enumerate possible creation results for reporting.
+  enum CreateHistogramResultType {
+    // Everything was fine.
+    CREATE_HISTOGRAM_SUCCESS = 0,
+
+    // Pointer to metadata was not valid.
+    CREATE_HISTOGRAM_INVALID_METADATA_POINTER,
+
+    // Histogram metadata was not valid.
+    CREATE_HISTOGRAM_INVALID_METADATA,
+
+    // Ranges information was not valid.
+    CREATE_HISTOGRAM_INVALID_RANGES_ARRAY,
+
+    // Counts information was not valid.
+    CREATE_HISTOGRAM_INVALID_COUNTS_ARRAY,
+
+    // Could not allocate histogram memory due to corruption.
+    CREATE_HISTOGRAM_ALLOCATOR_CORRUPT,
+
+    // Could not allocate histogram memory due to lack of space.
+    CREATE_HISTOGRAM_ALLOCATOR_FULL,
+
+    // Could not allocate histogram memory due to unknown error.
+    CREATE_HISTOGRAM_ALLOCATOR_ERROR,
+
+    // Histogram was of unknown type.
+    CREATE_HISTOGRAM_UNKNOWN_TYPE,
+
+    // Instance has detected a corrupt allocator (recorded only once).
+    CREATE_HISTOGRAM_ALLOCATOR_NEWLY_CORRUPT,
+
+    // Always keep this at the end.
+    CREATE_HISTOGRAM_MAX
+  };
+
+  // The structure used to hold histogram data in persistent memory. It is
+  // defined and used entirely within the .cc file.
+  struct PersistentHistogramData;
+
+  // Get the next histogram in persistent data based on iterator while
+  // ignoring a particular reference if it is found.
+  scoped_ptr<HistogramBase> GetNextHistogramWithIgnore(
+      Iterator* iter,
+      Reference ignore);
+
+  // Create a histogram based on saved (persistent) information about it.
+  scoped_ptr<HistogramBase> CreateHistogram(
+      PersistentHistogramData* histogram_data_ptr);
+
+  // Record the result of a histogram creation.
+  static void RecordCreateHistogramResult(CreateHistogramResultType result);
+
+  // The memory allocator that provides the actual histogram storage.
+  scoped_ptr<PersistentMemoryAllocator> memory_allocator_;
+
+  // A reference to the last-created histogram in the allocator, used to avoid
+  // trying to import what was just created.
+  subtle::AtomicWord last_created_ = 0;
+
+  DISALLOW_COPY_AND_ASSIGN(PersistentHistogramAllocator);
+};
+
+}  // namespace base
+
+#endif  // BASE_METRICS_HISTOGRAM_PERSISTENCE_H_
diff --git a/base/metrics/persistent_histogram_allocator_unittest.cc b/base/metrics/persistent_histogram_allocator_unittest.cc
new file mode 100644
index 0000000..64abdec7
--- /dev/null
+++ b/base/metrics/persistent_histogram_allocator_unittest.cc
@@ -0,0 +1,126 @@
+// 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 "base/metrics/persistent_histogram_allocator.h"
+
+#include "base/logging.h"
+#include "base/metrics/bucket_ranges.h"
+#include "base/metrics/histogram_macros.h"
+#include "base/metrics/persistent_memory_allocator.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace base {
+
+class PersistentHistogramAllocatorTest : public testing::Test {
+ protected:
+  const int32_t kAllocatorMemorySize = 64 << 10;  // 64 KiB
+
+  PersistentHistogramAllocatorTest() { CreatePersistentHistogramAllocator(); }
+  ~PersistentHistogramAllocatorTest() override {
+    DestroyPersistentHistogramAllocator();
+  }
+
+  void CreatePersistentHistogramAllocator() {
+    allocator_memory_.reset(new char[kAllocatorMemorySize]);
+
+    PersistentHistogramAllocator::ReleaseGlobalAllocatorForTesting();
+    memset(allocator_memory_.get(), 0, kAllocatorMemorySize);
+    PersistentHistogramAllocator::GetCreateHistogramResultHistogram();
+    PersistentHistogramAllocator::CreateGlobalAllocatorOnPersistentMemory(
+        allocator_memory_.get(), kAllocatorMemorySize, 0, 0,
+        "PersistentHistogramAllocatorTest");
+    allocator_ =
+        PersistentHistogramAllocator::GetGlobalAllocator()->memory_allocator();
+  }
+
+  void DestroyPersistentHistogramAllocator() {
+    allocator_ = nullptr;
+    PersistentHistogramAllocator::ReleaseGlobalAllocatorForTesting();
+  }
+
+  scoped_ptr<char[]> allocator_memory_;
+  PersistentMemoryAllocator* allocator_ = nullptr;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(PersistentHistogramAllocatorTest);
+};
+
+TEST_F(PersistentHistogramAllocatorTest, CreateAndIterateTest) {
+  PersistentMemoryAllocator::MemoryInfo meminfo0;
+  allocator_->GetMemoryInfo(&meminfo0);
+
+  // Try basic construction
+  HistogramBase* histogram = Histogram::FactoryGet(
+      "TestHistogram", 1, 1000, 10, HistogramBase::kIsPersistent);
+  EXPECT_TRUE(histogram);
+  histogram->CheckName("TestHistogram");
+  PersistentMemoryAllocator::MemoryInfo meminfo1;
+  allocator_->GetMemoryInfo(&meminfo1);
+  EXPECT_GT(meminfo0.free, meminfo1.free);
+
+  HistogramBase* linear_histogram = LinearHistogram::FactoryGet(
+      "TestLinearHistogram", 1, 1000, 10, HistogramBase::kIsPersistent);
+  EXPECT_TRUE(linear_histogram);
+  linear_histogram->CheckName("TestLinearHistogram");
+  PersistentMemoryAllocator::MemoryInfo meminfo2;
+  allocator_->GetMemoryInfo(&meminfo2);
+  EXPECT_GT(meminfo1.free, meminfo2.free);
+
+  HistogramBase* boolean_histogram = BooleanHistogram::FactoryGet(
+      "TestBooleanHistogram", HistogramBase::kIsPersistent);
+  EXPECT_TRUE(boolean_histogram);
+  boolean_histogram->CheckName("TestBooleanHistogram");
+  PersistentMemoryAllocator::MemoryInfo meminfo3;
+  allocator_->GetMemoryInfo(&meminfo3);
+  EXPECT_GT(meminfo2.free, meminfo3.free);
+
+  std::vector<int> custom_ranges;
+  custom_ranges.push_back(1);
+  custom_ranges.push_back(5);
+  HistogramBase* custom_histogram = CustomHistogram::FactoryGet(
+      "TestCustomHistogram", custom_ranges, HistogramBase::kIsPersistent);
+  EXPECT_TRUE(custom_histogram);
+  custom_histogram->CheckName("TestCustomHistogram");
+  PersistentMemoryAllocator::MemoryInfo meminfo4;
+  allocator_->GetMemoryInfo(&meminfo4);
+  EXPECT_GT(meminfo3.free, meminfo4.free);
+
+  PersistentMemoryAllocator::Iterator iter;
+  uint32_t type;
+  allocator_->CreateIterator(&iter);
+  EXPECT_NE(0U, allocator_->GetNextIterable(&iter, &type));  // Histogram
+  EXPECT_NE(0U, allocator_->GetNextIterable(&iter, &type));  // LinearHistogram
+  EXPECT_NE(0U, allocator_->GetNextIterable(&iter, &type));  // BooleanHistogram
+  EXPECT_NE(0U, allocator_->GetNextIterable(&iter, &type));  // CustomHistogram
+  EXPECT_EQ(0U, allocator_->GetNextIterable(&iter, &type));
+
+  // Create a second allocator and have it access the memory of the first.
+  scoped_ptr<HistogramBase> recovered;
+  PersistentHistogramAllocator recovery(
+      make_scoped_ptr(new PersistentMemoryAllocator(
+          allocator_memory_.get(), kAllocatorMemorySize, 0, 0, "", false)));
+  PersistentHistogramAllocator::Iterator histogram_iter;
+  recovery.CreateIterator(&histogram_iter);
+
+  recovered = recovery.GetNextHistogram(&histogram_iter);
+  ASSERT_TRUE(recovered);
+  recovered->CheckName("TestHistogram");
+
+  recovered = recovery.GetNextHistogram(&histogram_iter);
+  ASSERT_TRUE(recovered);
+  recovered->CheckName("TestLinearHistogram");
+
+  recovered = recovery.GetNextHistogram(&histogram_iter);
+  ASSERT_TRUE(recovered);
+  recovered->CheckName("TestBooleanHistogram");
+
+  recovered = recovery.GetNextHistogram(&histogram_iter);
+  ASSERT_TRUE(recovered);
+  recovered->CheckName("TestCustomHistogram");
+
+  recovered = recovery.GetNextHistogram(&histogram_iter);
+  EXPECT_FALSE(recovered);
+}
+
+}  // namespace base
diff --git a/base/metrics/statistics_recorder_unittest.cc b/base/metrics/statistics_recorder_unittest.cc
index 17511a4..073cbb1 100644
--- a/base/metrics/statistics_recorder_unittest.cc
+++ b/base/metrics/statistics_recorder_unittest.cc
@@ -10,7 +10,7 @@
 #include "base/json/json_reader.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/metrics/histogram_macros.h"
-#include "base/metrics/histogram_persistence.h"
+#include "base/metrics/persistent_histogram_allocator.h"
 #include "base/metrics/sparse_histogram.h"
 #include "base/metrics/statistics_recorder.h"
 #include "base/values.h"
@@ -23,7 +23,7 @@
   void SetUp() override {
     // Get this first so it never gets created in persistent storage and will
     // not appear in the StatisticsRecorder after it is re-initialized.
-    GetCreateHistogramResultHistogram();
+    PersistentHistogramAllocator::GetCreateHistogramResultHistogram();
     // Each test will have a clean state (no Histogram / BucketRanges
     // registered).
     InitializeStatisticsRecorder();
@@ -31,7 +31,7 @@
 
   void TearDown() override {
     UninitializeStatisticsRecorder();
-    delete ReleasePersistentHistogramMemoryAllocatorForTesting();
+    PersistentHistogramAllocator::ReleaseGlobalAllocatorForTesting();
   }
 
   void InitializeStatisticsRecorder() {
@@ -325,8 +325,8 @@
 TEST_F(StatisticsRecorderTest, IterationTest) {
   StatisticsRecorder::Histograms registered_histograms;
   LOCAL_HISTOGRAM_COUNTS("TestHistogram.IterationTest1", 30);
-  SetPersistentHistogramMemoryAllocator(
-      new LocalPersistentMemoryAllocator(64 << 10, 0, std::string()));
+  PersistentHistogramAllocator::CreateGlobalAllocatorOnLocalMemory(
+      64 << 10 /* 64 KiB */, 0, "");
   LOCAL_HISTOGRAM_COUNTS("TestHistogram.IterationTest2", 30);
 
   StatisticsRecorder::HistogramIterator i1 = StatisticsRecorder::begin(true);
diff --git a/build/toolchain/win/setup_toolchain.py b/build/toolchain/win/setup_toolchain.py
index 7248ed24..df92f15 100644
--- a/build/toolchain/win/setup_toolchain.py
+++ b/build/toolchain/win/setup_toolchain.py
@@ -11,6 +11,7 @@
 # and the files will be written to the current directory.
 
 import errno
+import json
 import os
 import re
 import subprocess
@@ -67,35 +68,57 @@
   return vs_toolchain.DetectVisualStudioPath()
 
 
-def _SetupScript(target_cpu, sdk_dir):
-  """Returns a command (with arguments) to be used to set up the
-  environment."""
-  # Check if we are running in the SDK command line environment and use
-  # the setup script from the SDK if so. |target_cpu| should be either
-  # 'x86' or 'x64'.
-  assert target_cpu in ('x86', 'x64')
-  if bool(int(os.environ.get('DEPOT_TOOLS_WIN_TOOLCHAIN', 1))) and sdk_dir:
-    return [os.path.normpath(os.path.join(sdk_dir, 'Bin/SetEnv.Cmd')),
-            '/' + target_cpu]
-  else:
-    if 'GYP_MSVS_OVERRIDE_PATH' not in os.environ:
-      os.environ['GYP_MSVS_OVERRIDE_PATH'] = _DetectVisualStudioPath()
-    # We only support x64-hosted tools.
-    return [os.path.normpath(os.path.join(os.environ['GYP_MSVS_OVERRIDE_PATH'],
-                                          'VC/vcvarsall.bat')),
-            'amd64_x86' if target_cpu == 'x86' else 'amd64']
-
-
-def _LoadToolchainEnv(cpu, win_sdk_path):
-  """Returns a dictionary with environment variables that must be set while
-  running binaries from the toolchain (e.g. INCLUDE and PATH for cl.exe)."""
-  args = _SetupScript(cpu, win_sdk_path)
+def _LoadEnvFromBat(args):
+  """Given a bat command, runs it and returns env vars set by it."""
+  args = args[:]
   args.extend(('&&', 'set'))
   popen = subprocess.Popen(
       args, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
   variables, _ = popen.communicate()
   if popen.returncode != 0:
     raise Exception('"%s" failed with error %d' % (args, popen.returncode))
+  return variables
+
+
+def _LoadToolchainEnv(cpu, sdk_dir):
+  """Returns a dictionary with environment variables that must be set while
+  running binaries from the toolchain (e.g. INCLUDE and PATH for cl.exe)."""
+  # Check if we are running in the SDK command line environment and use
+  # the setup script from the SDK if so. |cpu| should be either
+  # 'x86' or 'x64'.
+  assert cpu in ('x86', 'x64')
+  if bool(int(os.environ.get('DEPOT_TOOLS_WIN_TOOLCHAIN', 1))) and sdk_dir:
+    # Load environment from json file.
+    env = os.path.normpath(os.path.join(sdk_dir, 'Bin/SetEnv.%s.json' % cpu))
+    env = json.load(open(env))['env']
+    for k in env:
+      entries = [os.path.join(*([os.path.join(sdk_dir, 'bin')] + e))
+                 for e in env[k]]
+      env[k] = os.pathsep.join(entries)
+    # PATH is a bit of a special case, it's in addition to the current PATH.
+    env['PATH'] = env['PATH'] + os.pathsep + os.environ['PATH']
+    # Augment with the current env to pick up TEMP and friends.
+    for k in os.environ:
+      if k not in env:
+        env[k] = os.environ[k]
+
+    varlines = []
+    for k in sorted(env.keys()):
+      varlines.append('%s=%s' % (str(k), str(env[k])))
+    variables = '\n'.join(varlines)
+
+    # Check that the json file contained the same environment as the .cmd file.
+    script = os.path.normpath(os.path.join(sdk_dir, 'Bin/SetEnv.cmd'))
+    assert _ExtractImportantEnvironment(variables) == \
+           _ExtractImportantEnvironment(_LoadEnvFromBat([script, '/' + cpu]))
+  else:
+    if 'GYP_MSVS_OVERRIDE_PATH' not in os.environ:
+      os.environ['GYP_MSVS_OVERRIDE_PATH'] = _DetectVisualStudioPath()
+    # We only support x64-hosted tools.
+    args = [os.path.normpath(os.path.join(os.environ['GYP_MSVS_OVERRIDE_PATH'],
+                                          'VC/vcvarsall.bat')),
+            'amd64_x86' if cpu == 'x86' else 'amd64']
+    variables = _LoadEnvFromBat(args)
   return _ExtractImportantEnvironment(variables)
 
 
diff --git a/chrome/VERSION b/chrome/VERSION
index f412fec..cc0759e 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=51
 MINOR=0
-BUILD=2680
+BUILD=2681
 PATCH=0
diff --git a/chrome/browser/chrome_browser_field_trials.cc b/chrome/browser/chrome_browser_field_trials.cc
index 682271f..2696ff0b 100644
--- a/chrome/browser/chrome_browser_field_trials.cc
+++ b/chrome/browser/chrome_browser_field_trials.cc
@@ -10,7 +10,7 @@
 #include "base/feature_list.h"
 #include "base/metrics/field_trial.h"
 #include "base/metrics/histogram_base.h"
-#include "base/metrics/histogram_persistence.h"
+#include "base/metrics/persistent_histogram_allocator.h"
 #include "base/strings/string_util.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
@@ -33,12 +33,12 @@
     // Create persistent/shared memory and allow histograms to be stored in it.
     // Memory that is not actualy used won't be physically mapped by the system.
     // BrowserMetrics usage peaked around 95% of 2MiB as of 2016-02-20.
-    base::SetPersistentHistogramMemoryAllocator(
-        new base::LocalPersistentMemoryAllocator(3 << 20,     // 3 MiB
-                                                 0x935DDD43,  // SHA1(B...M...)
-                                                 kAllocatorName));
-    base::GetPersistentHistogramMemoryAllocator()->CreateTrackingHistograms(
+    base::PersistentHistogramAllocator::CreateGlobalAllocatorOnLocalMemory(
+        3 << 20,     // 3 MiB
+        0x935DDD43,  // SHA1(BrowserMetrics)
         kAllocatorName);
+    base::PersistentHistogramAllocator::GetGlobalAllocator()
+        ->CreateTrackingHistograms(kAllocatorName);
   }
 }
 
diff --git a/chrome/browser/chromeos/preferences.cc b/chrome/browser/chromeos/preferences.cc
index 16a742d..ed640bd5 100644
--- a/chrome/browser/chromeos/preferences.cc
+++ b/chrome/browser/chromeos/preferences.cc
@@ -334,6 +334,9 @@
   previous_input_method_.Init(prefs::kLanguagePreviousInputMethod,
                               prefs, callback);
   ime_menu_activated_.Init(prefs::kLanguageImeMenuActivated, prefs, callback);
+  // Notifies the system tray to remove the IME items.
+  if (switches::IsImeMenuEnabled() && ime_menu_activated_.GetValue())
+    input_method::InputMethodManager::Get()->ImeMenuActivationChanged(true);
 
   xkb_auto_repeat_enabled_.Init(
       prefs::kLanguageXkbAutoRepeatEnabled, prefs, callback);
@@ -600,7 +603,8 @@
   }
 
   if (pref_name == prefs::kLanguageImeMenuActivated &&
-      (reason == REASON_PREF_CHANGED || reason == REASON_ACTIVE_USER_CHANGED)) {
+      (reason == REASON_PREF_CHANGED || reason == REASON_ACTIVE_USER_CHANGED) &&
+      switches::IsImeMenuEnabled()) {
     const bool activated = ime_menu_activated_.GetValue();
     input_method::InputMethodManager::Get()->ImeMenuActivationChanged(
         activated);
diff --git a/chrome/browser/extensions/api/settings_private/prefs_util.cc b/chrome/browser/extensions/api/settings_private/prefs_util.cc
index 5ec384c8..a509bbf 100644
--- a/chrome/browser/extensions/api/settings_private/prefs_util.cc
+++ b/chrome/browser/extensions/api/settings_private/prefs_util.cc
@@ -199,16 +199,26 @@
       settings_private::PrefType::PREF_TYPE_BOOLEAN;
   (*s_whitelist)["settings.a11y.autoclick_delay_ms"] =
       settings_private::PrefType::PREF_TYPE_BOOLEAN;
+  (*s_whitelist)["settings.a11y.caret_highlight"] =
+      settings_private::PrefType::PREF_TYPE_BOOLEAN;
+  (*s_whitelist)["settings.a11y.cursor_highlight"] =
+      settings_private::PrefType::PREF_TYPE_BOOLEAN;
   (*s_whitelist)["settings.a11y.enable_menu"] =
       settings_private::PrefType::PREF_TYPE_BOOLEAN;
+  (*s_whitelist)["settings.a11y.focus_highlight"] =
+      settings_private::PrefType::PREF_TYPE_BOOLEAN;
   (*s_whitelist)["settings.a11y.high_contrast_enabled"] =
       settings_private::PrefType::PREF_TYPE_BOOLEAN;
   (*s_whitelist)["settings.a11y.large_cursor_enabled"] =
       settings_private::PrefType::PREF_TYPE_BOOLEAN;
   (*s_whitelist)["settings.a11y.screen_magnifier"] =
       settings_private::PrefType::PREF_TYPE_BOOLEAN;
+  (*s_whitelist)["settings.a11y.select_to_speak"] =
+      settings_private::PrefType::PREF_TYPE_BOOLEAN;
   (*s_whitelist)["settings.a11y.sticky_keys_enabled"] =
       settings_private::PrefType::PREF_TYPE_BOOLEAN;
+  (*s_whitelist)["settings.a11y.switch_access"] =
+      settings_private::PrefType::PREF_TYPE_BOOLEAN;
   (*s_whitelist)["settings.a11y.virtual_keyboard"] =
       settings_private::PrefType::PREF_TYPE_BOOLEAN;
   (*s_whitelist)["settings.clock.use_24hour_clock"] =
diff --git a/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.html b/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.html
index 9c8f373e..23e5d7f06 100644
--- a/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.html
+++ b/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.html
@@ -99,9 +99,9 @@
         <paper-spinner id="searching-devices-spinner" active
             hidden$="[[computeSpinnerHidden_(justOpened_)]]">
         </paper-spinner>
-        <a href="[[deviceMissingUrl]]">
-          <span hidden$="[[!computeSpinnerHidden_(justOpened_)]]"
-              >[[deviceMissingText_]]</span>
+        <a href="[[deviceMissingUrl]]"
+            hidden$="[[!computeSpinnerHidden_(justOpened_)]]">
+          [[deviceMissingText_]]
         </a>
       </div>
       <paper-menu id="sink-list"
diff --git a/chrome/browser/resources/media_router/elements/media_router_header/media_router_header.css b/chrome/browser/resources/media_router/elements/media_router_header/media_router_header.css
index 42d3a1c..cdd86acc 100644
--- a/chrome/browser/resources/media_router/elements/media_router_header/media_router_header.css
+++ b/chrome/browser/resources/media_router/elements/media_router_header/media_router_header.css
@@ -37,6 +37,8 @@
 
 #header-and-arrow-container {
   display: flex;
+  overflow: hidden;
+  white-space: nowrap;
 }
 
 #header-text {
@@ -44,6 +46,8 @@
   color: white;
   font-size: 1.175em;
   margin: 0;
+  overflow: hidden;
+  text-overflow: ellipsis;
 }
 
 paper-icon-button {
diff --git a/chrome/browser/resources/options/language_options.js b/chrome/browser/resources/options/language_options.js
index f982551..4117c5c 100644
--- a/chrome/browser/resources/options/language_options.js
+++ b/chrome/browser/resources/options/language_options.js
@@ -265,6 +265,10 @@
         if (loadTimeData.getBoolean('enableLanguageOptionsImeMenu'))
           $('language-options-ime-menu-template').hidden = false;
 
+        // Updates the initial checked state of the check box.
+        Preferences.getInstance().addEventListener(
+            ACTIVATE_IME_MENU_PREF, this.updateImeMenuCheckbox_.bind(this));
+
         // Listen to check on 'activate-ime-menu' checkbox.
         var checkboxImeMenu = $('activate-ime-menu');
         checkboxImeMenu.addEventListener('click',
@@ -1395,6 +1399,15 @@
                                    checkbox.checked, true);
       }
     },
+
+    /**
+     * Updates the activate-ime-menu check box's checked state.
+     * @param {Event} e Change event.
+     * @private
+     */
+    updateImeMenuCheckbox_: function(e) {
+      $('activate-ime-menu').checked = e.value.value;
+    },
   };
 
   /**
diff --git a/chrome/browser/resources/settings/a11y_page/a11y_page.html b/chrome/browser/resources/settings/a11y_page/a11y_page.html
index 5325098..b8e37d18 100644
--- a/chrome/browser/resources/settings/a11y_page/a11y_page.html
+++ b/chrome/browser/resources/settings/a11y_page/a11y_page.html
@@ -58,6 +58,23 @@
       <settings-checkbox pref="{{prefs.settings.a11y.virtual_keyboard}}"
           i18n-values="label:onScreenKeyboardLabel">
       </settings-checkbox>
+      <template is="dom-if" if="[[showExperimentalFeatures_]]">
+        <settings-checkbox pref="{{prefs.settings.a11y.caret_highlight}}"
+            i18n-values="label:caretHighlightLabel">
+        </settings-checkbox>
+        <settings-checkbox pref="{{prefs.settings.a11y.cursor_highlight}}"
+            i18n-values="label:cursorHighlightLabel">
+        </settings-checkbox>
+        <settings-checkbox pref="{{prefs.settings.a11y.focus_highlight}}"
+            i18n-values="label:focusHighlightLabel">
+        </settings-checkbox>
+        <settings-checkbox pref="{{prefs.settings.a11y.select_to_speak}}"
+            i18n-values="label:selectToSpeakLabel">
+        </settings-checkbox>
+        <settings-checkbox pref="{{prefs.settings.a11y.switch_access}}"
+            i18n-values="label:switchAccessLabel">
+        </settings-checkbox>
+      </template>
     </div>
 
     <div class="settings-box">
diff --git a/chrome/browser/resources/settings/a11y_page/a11y_page.js b/chrome/browser/resources/settings/a11y_page/a11y_page.js
index dbb55f3..109c99e 100644
--- a/chrome/browser/resources/settings/a11y_page/a11y_page.js
+++ b/chrome/browser/resources/settings/a11y_page/a11y_page.js
@@ -25,6 +25,17 @@
       type: Object,
       notify: true,
     },
+
+    /**
+     * Whether to show experimental accessibility features.
+     * @private {boolean}
+     */
+    showExperimentalFeatures_: {
+      type: Boolean,
+      value: function() {
+        return loadTimeData.getBoolean('showExperimentalA11yFeatures');
+      },
+    }
   },
 
   /** @private */
diff --git a/chrome/browser/resources/settings/advanced_page/advanced_page.html b/chrome/browser/resources/settings/advanced_page/advanced_page.html
index 07482356..3623aa81 100644
--- a/chrome/browser/resources/settings/advanced_page/advanced_page.html
+++ b/chrome/browser/resources/settings/advanced_page/advanced_page.html
@@ -5,6 +5,7 @@
 <link rel="import" href="chrome://md-settings/passwords_and_forms_page/passwords_and_forms_page.html">
 <link rel="import" href="chrome://md-settings/privacy_page/privacy_page.html">
 <link rel="import" href="chrome://md-settings/reset_page/reset_page.html">
+<link rel="import" href="chrome://md-settings/settings_page/main_page_behavior.html">
 <link rel="import" href="chrome://md-settings/settings_page/settings_page_visibility.html">
 <link rel="import" href="chrome://md-settings/settings_page/settings_section.html">
 <link rel="import" href="chrome://md-settings/site_settings/constants.html">
@@ -24,6 +25,7 @@
 <dom-module id="settings-advanced-page">
   <link rel="import" type="css" href="chrome://md-settings/settings_page.css">
   <template>
+    <style include="main-page-styles"></style>
 <if expr="chromeos">
     <template is="dom-if" if="[[showPage(pageVisibility.dateTime)]]" restamp>
       <settings-section page-title="[[i18n('dateTimePageTitle')]]"
diff --git a/chrome/browser/resources/settings/advanced_page/advanced_page.js b/chrome/browser/resources/settings/advanced_page/advanced_page.js
index ddc47fe..e6655247 100644
--- a/chrome/browser/resources/settings/advanced_page/advanced_page.js
+++ b/chrome/browser/resources/settings/advanced_page/advanced_page.js
@@ -18,6 +18,8 @@
 Polymer({
   is: 'settings-advanced-page',
 
+  behaviors: [I18nBehavior, SettingsPageVisibility, RoutableBehavior],
+
   properties: {
     /**
      * Preferences state.
@@ -36,11 +38,26 @@
     },
   },
 
+  /**
+   * @type {string} Selector to get the sections.
+   * TODO(michaelpg): replace duplicate docs with @override once b/24294625
+   * is fixed.
+   */
+  sectionSelector: 'settings-section',
+
 <if expr="not chromeos">
   listeners: {
     'dom-change': 'onDomChange_',
   },
+</if>
 
+  /** @override */
+  attached: function() {
+    /** @override */
+    this.scroller = this.parentElement;
+  },
+
+<if expr="not chromeos">
   /** @private */
   onDomChange_: function() {
     var systemPage = /** @type {?SettingsSystemPageElement} */(
@@ -49,6 +66,4 @@
       systemPage.delegate = new settings.SystemPageDelegateImpl;
   },
 </if>
-
-  behaviors: [I18nBehavior, SettingsPageVisibility],
 });
diff --git a/chrome/browser/resources/settings/advanced_page/compiled_resources2.gyp b/chrome/browser/resources/settings/advanced_page/compiled_resources2.gyp
index a8e444d..ee927f3 100644
--- a/chrome/browser/resources/settings/advanced_page/compiled_resources2.gyp
+++ b/chrome/browser/resources/settings/advanced_page/compiled_resources2.gyp
@@ -7,7 +7,9 @@
       'target_name': 'advanced_page',
       'dependencies': [
         '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior',
+        '../settings_page/compiled_resources2.gyp:main_page_behavior',
         '../settings_page/compiled_resources2.gyp:settings_page_visibility',
+        '../settings_page/compiled_resources2.gyp:transition_behavior',
         '../system_page/compiled_resources2.gyp:system_page',
         '../system_page/compiled_resources2.gyp:system_page_delegate',
       ],
diff --git a/chrome/browser/resources/settings/basic_page/basic_page.html b/chrome/browser/resources/settings/basic_page/basic_page.html
index f94aa390..7f9fc4e 100644
--- a/chrome/browser/resources/settings/basic_page/basic_page.html
+++ b/chrome/browser/resources/settings/basic_page/basic_page.html
@@ -2,6 +2,7 @@
 <link rel="import" href="chrome://resources/html/polymer.html">
 <link rel="import" href="chrome://md-settings/appearance_page/appearance_page.html">
 <link rel="import" href="chrome://md-settings/search_page/search_page.html">
+<link rel="import" href="chrome://md-settings/settings_page/main_page_behavior.html">
 <link rel="import" href="chrome://md-settings/settings_page/settings_page_visibility.html">
 <link rel="import" href="chrome://md-settings/settings_page/settings_section.html">
 <link rel="import" href="chrome://md-settings/on_startup_page/on_startup_page.html">
@@ -20,6 +21,7 @@
 <dom-module id="settings-basic-page">
   <link rel="import" type="css" href="chrome://md-settings/settings_page.css">
   <template>
+    <style include="main-page-styles"></style>
     <template is="dom-if" if="[[showResetProfileBanner_]]">
       <settings-reset-profile-banner on-reset-done="onResetDone_">
       </settings-reset-profile-banner>
diff --git a/chrome/browser/resources/settings/basic_page/basic_page.js b/chrome/browser/resources/settings/basic_page/basic_page.js
index 0e84e86..80787fc 100644
--- a/chrome/browser/resources/settings/basic_page/basic_page.js
+++ b/chrome/browser/resources/settings/basic_page/basic_page.js
@@ -46,7 +46,20 @@
 
   },
 
-  behaviors: [I18nBehavior, SettingsPageVisibility],
+  /**
+   * @type {string} Selector to get the sections.
+   * TODO(michaelpg): replace duplicate docs with @override once b/24294625
+   * is fixed.
+   */
+  sectionSelector: 'settings-section',
+
+  /** @override */
+  attached: function() {
+    /** @override */
+    this.scroller = this.parentElement;
+  },
+
+  behaviors: [I18nBehavior, SettingsPageVisibility, RoutableBehavior],
 
   onResetDone_: function() {
     this.showResetProfileBanner_ = false;
diff --git a/chrome/browser/resources/settings/basic_page/compiled_resources2.gyp b/chrome/browser/resources/settings/basic_page/compiled_resources2.gyp
index 6c0c9d8..b3013ed 100644
--- a/chrome/browser/resources/settings/basic_page/compiled_resources2.gyp
+++ b/chrome/browser/resources/settings/basic_page/compiled_resources2.gyp
@@ -8,7 +8,9 @@
       'dependencies': [
         '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:load_time_data',
         '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior',
+        '../settings_page/compiled_resources2.gyp:main_page_behavior',
         '../settings_page/compiled_resources2.gyp:settings_page_visibility',
+        '../settings_page/compiled_resources2.gyp:transition_behavior',
       ],
       'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'],
     },
diff --git a/chrome/browser/resources/settings/settings_main/settings_main.css b/chrome/browser/resources/settings/settings_main/settings_main.css
index 2624d9aed..7932a8d 100644
--- a/chrome/browser/resources/settings/settings_main/settings_main.css
+++ b/chrome/browser/resources/settings/settings_main/settings_main.css
@@ -6,10 +6,6 @@
   box-sizing: border-box;
   height: 100%;
   overflow: auto;
-  padding: 24px 16px;
-}
-
-#pageContainer.expanded {
   padding: 0 16px;
 }
 
diff --git a/chrome/browser/resources/settings/settings_main/settings_main.js b/chrome/browser/resources/settings/settings_main/settings_main.js
index 0b46de37..766e9dde 100644
--- a/chrome/browser/resources/settings/settings_main/settings_main.js
+++ b/chrome/browser/resources/settings/settings_main/settings_main.js
@@ -43,35 +43,8 @@
     }
   },
 
-  listeners: {
-    'expand-animation-complete': 'onExpandAnimationComplete_',
-  },
-
   /** @private */
   currentRouteChanged_: function(newRoute, oldRoute) {
     this.showAdvancedPage_ = newRoute.page == 'advanced';
-
-    var pageContainer = this.$.pageContainer;
-    if (!oldRoute) {
-      pageContainer.classList.toggle('expanded', newRoute.section);
-      return;
-    }
-
-    // For contraction only, apply new styling immediately.
-    if (!newRoute.section && oldRoute.section) {
-      pageContainer.classList.remove('expanded');
-
-      // TODO(tommycli): Save and restore scroll position. crbug.com/537359.
-      pageContainer.scrollTop = 0;
-    }
-  },
-
-  /** @private */
-  onExpandAnimationComplete_: function() {
-    if (this.currentRoute.section) {
-      var pageContainer = this.$.pageContainer;
-      pageContainer.classList.add('expanded');
-      pageContainer.scrollTop = 0;
-    }
   },
 });
diff --git a/chrome/browser/resources/settings/settings_page.css b/chrome/browser/resources/settings/settings_page.css
index 9e44ff94..78d34a06 100644
--- a/chrome/browser/resources/settings/settings_page.css
+++ b/chrome/browser/resources/settings/settings_page.css
@@ -5,8 +5,13 @@
 :host {
   display: block;
   height: 100%;
-  margin: auto;
+  margin: 24px auto;
   max-width: 960px;
   min-width: 622px;
+  position: relative;
   width: 80%;
 }
+
+:host > * {
+  margin-bottom: 16px;
+}
diff --git a/chrome/browser/resources/settings/settings_page/compiled_resources2.gyp b/chrome/browser/resources/settings/settings_page/compiled_resources2.gyp
index c422dff..af8bcca3 100644
--- a/chrome/browser/resources/settings/settings_page/compiled_resources2.gyp
+++ b/chrome/browser/resources/settings/settings_page/compiled_resources2.gyp
@@ -4,6 +4,16 @@
 {
   'targets': [
     {
+      'target_name': 'main_page_behavior',
+      'dependencies': [
+        'settings_section',
+        'transition_behavior',
+        '<(EXTERNS_GYP):settings_private',
+        '<(EXTERNS_GYP):web_animations',
+      ],
+      'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'],
+    },
+    {
       'target_name': 'settings_animated_pages',
       'dependencies': [
         '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:assert',
@@ -23,5 +33,17 @@
       ],
       'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'],
     },
+    {
+      'target_name': 'settings_section',
+      'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'],
+    },
+    {
+      'target_name': 'transition_behavior',
+      'dependencies': [
+        '<(EXTERNS_GYP):settings_private',
+        '<(EXTERNS_GYP):web_animations',
+      ],
+      'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'],
+    },
   ],
 }
diff --git a/chrome/browser/resources/settings/settings_page/main_page_behavior.html b/chrome/browser/resources/settings/settings_page/main_page_behavior.html
new file mode 100644
index 0000000..3d1c94f
--- /dev/null
+++ b/chrome/browser/resources/settings/settings_page/main_page_behavior.html
@@ -0,0 +1,18 @@
+<link rel="import" href="chrome://resources/html/polymer.html">
+<link rel="import" href="chrome://md-settings/settings_page/transition_behavior.html">
+<script src="chrome://md-settings/settings_page/main_page_behavior.js"></script>
+
+<dom-module id="main-page-styles">
+  <template>
+    <style>
+      .expanding,
+      .collapsing {
+        z-index: 2;
+      }
+
+      .expanded {
+        min-height: 100%;
+      }
+    </style>
+  </template>
+</dom-module>
diff --git a/chrome/browser/resources/settings/settings_page/main_page_behavior.js b/chrome/browser/resources/settings/settings_page/main_page_behavior.js
new file mode 100644
index 0000000..99dbc67
--- /dev/null
+++ b/chrome/browser/resources/settings/settings_page/main_page_behavior.js
@@ -0,0 +1,379 @@
+// 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.
+
+// Fast out, slow in.
+var EASING_FUNCTION = 'cubic-bezier(0.4, 0, 0.2, 1)';
+var EXPAND_DURATION = 350;
+
+/**
+ * Provides animations to expand and collapse individual sections in a page.
+ * Expanded sections take up the full height of the container. At most one
+ * section should be expanded at any given time.
+ * @polymerBehavior Polymer.MainPageBehavior
+ */
+var MainPageBehaviorImpl = {
+  /**
+   * @type {string} Selector to get the sections. Derived elements
+   *     must override.
+   */
+  sectionSelector: '',
+
+  /** @type {?Element} The scrolling container. Elements must set this. */
+  scroller: null,
+
+  /**
+   * Hides or unhides the sections not being expanded.
+   * @param {string} sectionName The section to keep visible.
+   * @param {boolean} hidden Whether the sections should be hidden.
+   * @private
+   */
+  toggleOtherSectionsHidden_: function(sectionName, hidden) {
+    var sections = Polymer.dom(this.root).querySelectorAll(
+        this.sectionSelector + ':not([section=' + sectionName + '])');
+    for (var section of sections)
+      section.hidden = hidden;
+  },
+
+  /**
+   * Animates the card in |section|, expanding it to fill the page.
+   * @param {!SettingsSectionElement} section
+   */
+  expandSection: function(section) {
+    // If another section's card is expanding, cancel that animation first.
+    var expanding = this.$$('.expanding');
+    if (expanding) {
+      if (expanding == section)
+        return;
+
+      if (this.animations['section']) {
+        // Cancel the animation, then call startExpandSection_.
+        this.cancelAnimation('section', function() {
+          this.startExpandSection_(section);
+        }.bind(this));
+      } else {
+        // The animation must have finished but its promise hasn't resolved yet.
+        // When it resolves, collapse that section's card before expanding
+        // this one.
+        setTimeout(function() {
+          this.collapseSection(
+              /** @type {!SettingsSectionElement} */(expanding));
+          this.finishAnimation('section', function() {
+            this.startExpandSection_(section);
+          }.bind(this));
+        }.bind(this));
+      }
+
+      return;
+    }
+
+    if (this.$$('.collapsing') && this.animations['section']) {
+      // Finish the collapse animation before expanding.
+      this.finishAnimation('section', function() {
+        this.startExpandSection_(section);
+      }.bind(this));
+      return;
+    }
+
+    this.startExpandSection_(section);
+  },
+
+  /**
+   * Helper function to set up and start the expand animation.
+   * @param {!SettingsSectionElement} section
+   */
+  startExpandSection_: function(section) {
+    if (section.classList.contains('expanded'))
+      return;
+
+    // Freeze the scroller and save its position.
+    this.listScrollTop_ = this.scroller.scrollTop;
+
+    var scrollerWidth = this.scroller.clientWidth;
+    this.scroller.style.overflow = 'hidden';
+    // Adjust width to compensate for scroller.
+    var scrollbarWidth = this.scroller.clientWidth - scrollerWidth;
+    this.scroller.style.width = 'calc(100% - ' + scrollbarWidth + 'px)';
+
+    // Freezes the section's height so its card can be removed from the flow.
+    this.freezeSection_(section);
+
+    // Expand the section's card to fill the parent.
+    var animationPromise = this.playExpandSection_(section);
+
+    animationPromise.then(function() {
+      this.scroller.scrollTop = 0;
+      this.toggleOtherSectionsHidden_(section.section, true);
+    }.bind(this), function() {
+      // Animation was canceled; restore the section.
+      this.unfreezeSection_(section);
+    }.bind(this)).then(function() {
+      this.scroller.style.overflow = '';
+      this.scroller.style.width = '';
+    }.bind(this));
+  },
+
+  /**
+   * Animates the card in |section|, collapsing it back into its section.
+   * @param {!SettingsSectionElement} section
+   */
+  collapseSection: function(section) {
+    // If the section's card is still expanding, cancel the expand animation.
+    if (section.classList.contains('expanding')) {
+      if (this.animations['section']) {
+        this.cancelAnimation('section');
+      } else {
+        // The animation must have finished but its promise hasn't finished
+        // resolving; try again asynchronously.
+        this.async(function() {
+          this.collapseSection(section);
+        });
+      }
+      return;
+    }
+
+    if (!section.classList.contains('expanded'))
+      return;
+
+    this.toggleOtherSectionsHidden_(section.section, false);
+
+    var scrollerWidth = this.scroller.clientWidth;
+    this.scroller.style.overflow = 'hidden';
+    // Adjust width to compensate for scroller.
+    var scrollbarWidth = this.scroller.clientWidth - scrollerWidth;
+    this.scroller.style.width = 'calc(100% - ' + scrollbarWidth + 'px)';
+
+    this.playCollapseSection_(section).then(function() {
+      this.unfreezeSection_(section);
+      this.scroller.style.overflow = '';
+      this.scroller.style.width = '';
+      section.classList.remove('collapsing');
+    }.bind(this));
+  },
+
+  /**
+   * Freezes a section's height so its card can be removed from the flow without
+   * affecting the layout of the surrounding sections.
+   * @param {!SettingsSectionElement} section
+   * @private
+   */
+  freezeSection_: function(section) {
+    var card = section.$.card;
+    section.style.height = section.clientHeight + 'px';
+
+    var cardHeight = card.offsetHeight;
+    var cardWidth = card.offsetWidth;
+    // If the section is not displayed yet (e.g., navigated directly to a
+    // sub-page), cardHeight and cardWidth are 0, so do not set the height or
+    // width explicitly.
+    // TODO(michaelpg): Improve this logic when refactoring
+    // settings-animated-pages.
+    if (cardHeight && cardWidth) {
+      // TODO(michaelpg): Temporary hack to store the height the section should
+      // collapse to when it closes.
+      card.origHeight_ = cardHeight;
+
+      card.style.height = cardHeight + 'px';
+      card.style.width = cardWidth + 'px';
+    } else {
+      // Set an invalid value so we don't try to use it later.
+      card.origHeight_ = NaN;
+    }
+
+    // Place the section's card at its current position but removed from the
+    // flow.
+    card.style.top = card.getBoundingClientRect().top + 'px';
+    section.classList.add('frozen');
+  },
+
+  /**
+   * After freezeSection_, restores the section to its normal height.
+   * @param {!SettingsSectionElement} section
+   * @private
+   */
+  unfreezeSection_: function(section) {
+    if (!section.classList.contains('frozen'))
+      return;
+    var card = section.$.card;
+    section.classList.remove('frozen');
+    card.style.top = '';
+    card.style.height = '';
+    card.style.width = '';
+    section.style.height = '';
+  },
+
+  /**
+   * Expands the card in |section| to fill the page.
+   * @param {!SettingsSectionElement} section
+   * @return {!Promise}
+   * @private
+   */
+  playExpandSection_: function(section) {
+    var card = section.$.card;
+
+    // The card should start at the top of the page.
+    var targetTop = this.parentElement.getBoundingClientRect().top;
+
+    section.classList.add('expanding');
+
+    // Expand the card, using minHeight. (The card must span the container's
+    // client height, so it must be at least 100% in case the card is too short.
+    // If the card is already taller than the container's client height, we
+    // don't want to shrink the card to 100% or the content will overflow, so
+    // we can't use height, and animating height wouldn't look right anyway.)
+    var keyframes = [{
+      top: card.style.top,
+      minHeight: card.style.height,
+      easing: EASING_FUNCTION,
+    }, {
+      top: targetTop + 'px',
+      minHeight: 'calc(100% - ' + targetTop + 'px)',
+    }];
+    var options = /** @type {!KeyframeEffectOptions} */({
+      duration: EXPAND_DURATION
+    });
+    // TODO(michaelpg): Change elevation of sections.
+    var promise;
+    if (keyframes[0].top && keyframes[0].minHeight)
+      promise = this.animateElement('section', card, keyframes, options);
+    else
+      promise = Promise.resolve();
+
+    promise.then(function() {
+      section.classList.add('expanded');
+      card.style.top = '';
+      this.style.margin = 'auto';
+      section.$.header.hidden = true;
+      section.style.height = '';
+    }.bind(this), function() {
+      // The animation was canceled; catch the error and continue.
+    }).then(function() {
+      // Whether finished or canceled, clean up the animation.
+      section.classList.remove('expanding');
+      card.style.height = '';
+    });
+
+    return promise;
+  },
+
+  /**
+   * Collapses the card in |section| back to its normal position.
+   * @param {!SettingsSectionElement} section
+   * @return {!Promise}
+   * @private
+   */
+  playCollapseSection_: function(section) {
+    var card = section.$.card;
+    var cardStyle = getComputedStyle(card);
+
+    this.style.margin = '';
+    section.$.header.hidden = false;
+
+    var startingTop = this.parentElement.getBoundingClientRect().top;
+
+    var cardHeightStart = card.clientHeight;
+
+    section.classList.add('collapsing');
+    section.classList.remove('expanding', 'expanded');
+
+    // If we navigated here directly, we don't know the original height of the
+    // section, so we skip the animation.
+    // TODO(michaelpg): remove this condition once sliding is implemented.
+    if (isNaN(card.origHeight_))
+      return Promise.resolve();
+
+    // Restore the section to its proper height to make room for the card.
+    section.style.height = section.clientHeight + card.origHeight_ + 'px';
+
+    // TODO(michaelpg): this should be in collapseSection(), but we need to wait
+    // until the full page height is available (setting the section height).
+    this.scroller.scrollTop = this.listScrollTop_;
+
+    // The card is unpositioned, so use its position as the ending state,
+    // but account for scroll.
+    var targetTop = card.getBoundingClientRect().top - this.scroller.scrollTop;
+
+    var keyframes = [{
+      top: startingTop + 'px',
+      minHeight: cardHeightStart + 'px',
+      easing: EASING_FUNCTION,
+    }, {
+      top: targetTop + 'px',
+      minHeight: card.origHeight_ + 'px',
+    }];
+    var options = /** @type {!KeyframeEffectOptions} */({
+      duration: EXPAND_DURATION
+    });
+    var promise = this.animateElement('section', card, keyframes, options);
+    return promise;
+  },
+};
+
+/** @polymerBehavior */
+var MainPageBehavior = [
+  TransitionBehavior,
+  MainPageBehaviorImpl
+];
+
+/**
+ * TODO(michaelpg): integrate slide animations.
+ * @polymerBehavior RoutableBehavior
+ */
+var RoutableBehaviorImpl = {
+  properties: {
+    /** Contains the current route. */
+    currentRoute: {
+      type: Object,
+      notify: true,
+      observer: 'currentRouteChanged_',
+    },
+  },
+
+  /** @private */
+  currentRouteChanged_: function(newRoute, oldRoute) {
+    // route.section is only non-empty when the user is within a subpage.
+    // When the user is not in a subpage, but on the Basic page, route.section
+    // is an empty string.
+    var newRouteIsSubpage = newRoute && newRoute.section;
+    var oldRouteIsSubpage = oldRoute && oldRoute.section;
+
+    if (!oldRoute && newRouteIsSubpage) {
+      // Allow the page to load before expanding the section. TODO(michaelpg):
+      // Time this better when refactoring settings-animated-pages.
+      setTimeout(function() {
+        var section = this.getSection_(newRoute.section);
+        if (section)
+          this.expandSection(section);
+      }.bind(this));
+      return;
+    }
+
+    if (!newRouteIsSubpage && oldRouteIsSubpage) {
+      var section = this.getSection_(oldRoute.section);
+      if (section)
+        this.collapseSection(section);
+    } else if (newRouteIsSubpage &&
+               (!oldRouteIsSubpage || newRoute.section != oldRoute.section)) {
+      var section = this.getSection_(newRoute.section);
+      if (section)
+        this.expandSection(section);
+    }
+  },
+
+  /**
+   * Helper function to get a section from the local DOM.
+   * @param {string} section Section name of the element to get.
+   * @return {?SettingsSectionElement}
+   * @private
+   */
+  getSection_: function(section) {
+    return /** @type {?SettingsSectionElement} */(
+        this.$$('[section=' + section + ']'));
+  },
+};
+
+/** @polymerBehavior */
+var RoutableBehavior = [
+  MainPageBehavior,
+  RoutableBehaviorImpl
+];
diff --git a/chrome/browser/resources/settings/settings_page/settings_section.css b/chrome/browser/resources/settings/settings_page/settings_section.css
index f0c37a91..85d6e91 100644
--- a/chrome/browser/resources/settings/settings_page/settings_section.css
+++ b/chrome/browser/resources/settings/settings_page/settings_section.css
@@ -7,15 +7,9 @@
  * Common styles for Settings pages.
  */
 :host {
-  display: block;
-}
-
-:host(.expanded) {
-  height: 100%;
-}
-
-:host(.expanded) #header {
-  display: none;
+  display: flex;
+  flex-direction: column;
+  position: relative;
 }
 
 #header {
@@ -28,31 +22,28 @@
   font-weight: 500;
 }
 
-paper-material {
+#card {
   background-color: white;
-  box-sizing: border-box;
   overflow: hidden;
 }
 
-paper-material,
-#placeholder {
-  margin-bottom: 16px;
+#card {
+  flex: 1;
 }
 
-:host(.neon-animating) paper-material {
-  position: fixed;
-  z-index: 1;
-}
-
-:host(.expanded) paper-material {
+:host(.expanded) {
   margin-bottom: 0;
-  min-height: 100%;
 }
 
-#placeholder {
-  visibility: hidden;
+:host(.expanded) #header {
+  display: none;
 }
 
-:host(:not(.neon-animating)) #placeholder {
-  position: absolute;
+:host(.frozen) #card {
+  position: fixed;
+  width: 100%;
+}
+
+:host(.expanded.frozen) #card {
+  position: relative;
 }
diff --git a/chrome/browser/resources/settings/settings_page/settings_section.html b/chrome/browser/resources/settings/settings_page/settings_section.html
index 344dc76..ed4e263 100644
--- a/chrome/browser/resources/settings/settings_page/settings_section.html
+++ b/chrome/browser/resources/settings/settings_page/settings_section.html
@@ -11,7 +11,6 @@
     <paper-material id="card" animated>
       <content id="content"></content>
     </paper-material>
-    <div id="placeholder"></div>
   </template>
   <script src="settings_section.js"></script>
 </dom-module>
diff --git a/chrome/browser/resources/settings/settings_page/settings_section.js b/chrome/browser/resources/settings/settings_page/settings_section.js
index 1365dad..1149e2ea 100644
--- a/chrome/browser/resources/settings/settings_page/settings_section.js
+++ b/chrome/browser/resources/settings/settings_page/settings_section.js
@@ -16,18 +16,11 @@
 Polymer({
   is: 'settings-section',
 
-  behaviors: [
-    Polymer.NeonAnimationRunnerBehavior,
-  ],
-
   properties: {
     /**
      * The current active route.
      */
-    currentRoute: {
-      type: Object,
-      observer: 'currentRouteChanged_',
-    },
+    currentRoute: Object,
 
     /**
      * The section is expanded to a full-page view when this property matches
@@ -43,143 +36,5 @@
      * Title for the page header and navigation menu.
      */
     pageTitle: String,
-
-    animationConfig: {
-      value: function() {
-        return {
-          collapse: {
-            name: 'collapse-card-animation',
-            node: this,
-          },
-          expand: {
-            name: 'expand-card-animation',
-            node: this,
-          },
-        };
-      },
-    },
   },
-
-  listeners: {
-    'expand-animation-complete': 'onExpandAnimationComplete_',
-  },
-
-  /** @private */
-  currentRouteChanged_: function(newRoute, oldRoute) {
-    var newExpanded = newRoute.section == this.section;
-    var oldExpanded = oldRoute && oldRoute.section == this.section;
-
-    var visible = newExpanded || this.currentRoute.section == '';
-
-    // If the user navigates directly to a subpage, skip all the animations.
-    if (!oldRoute) {
-      if (newExpanded) {
-        // If we navigate directly to a subpage, skip animations.
-        this.classList.add('expanded');
-      } else if (!visible) {
-        this.hidden = true;
-        this.$.card.elevation = 0;
-      }
-
-      return;
-    }
-
-    if (newExpanded && !oldExpanded) {
-      this.playAnimation('expand');
-    } else if (oldExpanded && !newExpanded) {
-      // For contraction, we defer the animation to allow
-      // settings-animated-pages to reflow the new page correctly.
-      this.async(function() {
-        this.playAnimation('collapse');
-      }.bind(this));
-    }
-
-    this.$.card.elevation = visible ? 1 : 0;
-
-    // Remove 'hidden' class immediately, but defer adding it if we are invisble
-    // until the animation is complete.
-    if (visible)
-      this.hidden = false;
-  },
-
-  /** @private */
-  onExpandAnimationComplete_: function() {
-    this.hidden = this.currentRoute.section != '' &&
-                  this.currentRoute.section != this.section;
-  },
-});
-
-Polymer({
-  is: 'expand-card-animation',
-
-  behaviors: [
-    Polymer.NeonAnimationBehavior
-  ],
-
-  configure: function(config) {
-    var section = config.node;
-    var card = section.$.card;
-    var containerRect = section.offsetParent.getBoundingClientRect();
-    var cardRect = card.getBoundingClientRect();
-
-    // Set placeholder height so the page does not reflow during animation.
-    // TODO(tommycli): For URLs that directly load subpages, this does not work.
-    var placeholder = section.$.placeholder;
-    placeholder.style.top = card.offsetTop + 'px';
-    placeholder.style.height = card.offsetHeight + 'px';
-
-    section.classList.add('neon-animating');
-
-    this._effect = new KeyframeEffect(card, [
-      {'top': cardRect.top + 'px', 'height': cardRect.height + 'px'},
-      {'top': containerRect.top + 'px', 'height': containerRect.height + 'px'},
-    ], this.timingFromConfig(config));
-    return this._effect;
-  },
-
-  complete: function(config) {
-    var section = config.node;
-    section.classList.remove('neon-animating');
-    section.classList.add('expanded');
-
-    // This event fires on itself as well, but that is benign.
-    var sections = section.parentNode.querySelectorAll('settings-section');
-    for (var i = 0; i < sections.length; ++i) {
-      sections[i].fire('expand-animation-complete');
-    }
-  }
-});
-
-Polymer({
-  is: 'collapse-card-animation',
-
-  behaviors: [
-    Polymer.NeonAnimationBehavior
-  ],
-
-  configure: function(config) {
-    var section = config.node;
-    var oldRect = section.offsetParent.getBoundingClientRect();
-
-    section.classList.remove('expanded');
-
-    var card = section.$.card;
-    var placeholder = section.$.placeholder;
-    placeholder.style.top = card.offsetTop + 'px';
-    placeholder.style.height = card.offsetHeight + 'px';
-
-    var newRect = card.getBoundingClientRect();
-
-    section.classList.add('neon-animating');
-
-    this._effect = new KeyframeEffect(card, [
-      {'top': oldRect.top + 'px', 'height': oldRect.height + 'px'},
-      {'top': newRect.top + 'px', 'height': newRect.height + 'px'},
-    ], this.timingFromConfig(config));
-    return this._effect;
-  },
-
-  complete: function(config) {
-    config.node.classList.remove('neon-animating');
-  }
 });
diff --git a/chrome/browser/resources/settings/settings_page/transition_behavior.html b/chrome/browser/resources/settings/settings_page/transition_behavior.html
new file mode 100644
index 0000000..c7c60bd0
--- /dev/null
+++ b/chrome/browser/resources/settings/settings_page/transition_behavior.html
@@ -0,0 +1,2 @@
+<link rel="import" href="chrome://resources/html/polymer.html">
+<script src="chrome://md-settings/settings_page/transition_behavior.js"></script>
diff --git a/chrome/browser/resources/settings/settings_page/transition_behavior.js b/chrome/browser/resources/settings/settings_page/transition_behavior.js
new file mode 100644
index 0000000..0aecfb39
--- /dev/null
+++ b/chrome/browser/resources/settings/settings_page/transition_behavior.js
@@ -0,0 +1,86 @@
+// 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 convenience functions to control native Web Animations. The
+ * implementation details may change as Chrome support evolves.
+ * @polymerBehavior
+ */
+var TransitionBehavior = {
+  ready: function() {
+    /**
+     * @type {!Object<!Animation>}
+     * Map of running animations by animation name. Animation names are
+     * arbitrary but used to prevent multiple animations of the same type (e.g.,
+     * expand/collapse section) from running simultaneously.
+     */
+    this.animations = {};
+
+    /**
+     * @private {!Object<!Promise>}
+     * Map of Promises for each running animation. Key names and existence
+     * should correspond with |animations|.
+     */
+    this.promises_ = {};
+  },
+
+  /**
+   * Calls el.animate(keyframes, opt_options). Returns a Promise which is
+   * resolved when the transition ends, or rejected when the transition is
+   * canceled. If an animation with the same name is in progress, that
+   * animation is finished immediately before creating the new animation.
+   * @param {string} name Name of the animation, used to finish this animation
+   *     when playing the same type of animation again.
+   * @param {!HTMLElement} el The element to animate.
+   * @param {!Array|!Object} keyframes Keyframes, as in Element.animate.
+   * @param {number|!KeyframeEffectOptions=} opt_options Options, as in
+   *     Element.animate.
+   * @return {!Promise} A promise which is resolved when the animation finishes
+   *     or rejected if the animation is canceled.
+   */
+  animateElement: function(name, el, keyframes, opt_options) {
+    if (this.animations[name])
+      this.animations[name].finish();
+
+    var animation = el.animate(keyframes, opt_options);
+    this.animations[name] = animation;
+
+    this.promises_[name] = new Promise(function(resolve, reject) {
+      animation.addEventListener('finish', function() {
+        this.animations[name] = undefined;
+        resolve();
+      }.bind(this));
+
+      animation.addEventListener('cancel', function() {
+        this.animations[name] = undefined;
+        reject();
+      }.bind(this));
+    }.bind(this));
+    return this.promises_[name];
+  },
+
+  /**
+   * Finishes the ongoing named animation, waits for the animation's Promise
+   * to be resolved, then calls the callback.
+   * @param {string} name Name of the animation passed to animateElement.
+   * @param {function()=} opt_callback Called once the animation finishes.
+   */
+  finishAnimation: function(name, opt_callback) {
+    if (opt_callback)
+      this.promises_[name].then(opt_callback);
+    this.animations[name].finish();
+  },
+
+  /**
+   * Cancels the ongoing named animation, waits for the animation's Promise
+   * to be rejected, then calls the callback.
+   * @param {string} name Name of the animation passed to animateElement.
+   * @param {function()=} opt_callback Called once the animation cancels.
+   */
+  cancelAnimation: function(name, opt_callback) {
+    if (opt_callback)
+      this.promises_[name].catch(opt_callback);
+    this.animations[name].cancel();
+  },
+};
diff --git a/chrome/browser/resources/settings/settings_resources.grd b/chrome/browser/resources/settings/settings_resources.grd
index d69f466..a70b4501 100644
--- a/chrome/browser/resources/settings/settings_resources.grd
+++ b/chrome/browser/resources/settings/settings_resources.grd
@@ -140,9 +140,21 @@
       <structure name="IDR_SETTINGS_CR_SETTINGS_PAGE_CSS"
                  file="settings_page.css"
                  type="chrome_html" />
+      <structure name="IDR_SETTINGS_MAIN_PAGE_BEHAVIOR_HTML"
+                 file="settings_page/main_page_behavior.html"
+                 type="chrome_html" />
+      <structure name="IDR_SETTINGS_MAIN_PAGE_BEHAVIOR_JS"
+                 file="settings_page/main_page_behavior.js"
+                 type="chrome_html" />
       <structure name="IDR_SETTINGS_SETTINGS_SHARED_CSS_HTML"
                  file="settings_shared_css.html"
                  type="chrome_html" />
+      <structure name="IDR_SETTINGS_TRANSITION_BEHAVIOR_HTML"
+                 file="settings_page/transition_behavior.html"
+                 type="chrome_html" />
+      <structure name="IDR_SETTINGS_TRANSITION_BEHAVIOR_JS"
+                 file="settings_page/transition_behavior.js"
+                 type="chrome_html" />
       <structure name="IDR_SETTINGS_BREADCRUMB_CSS"
                  file="settings_ui/breadcrumb.css"
                  type="chrome_html" />
diff --git a/chrome/browser/ui/ash/system_tray_delegate_chromeos.cc b/chrome/browser/ui/ash/system_tray_delegate_chromeos.cc
index b42266d..5eab3e7 100644
--- a/chrome/browser/ui/ash/system_tray_delegate_chromeos.cc
+++ b/chrome/browser/ui/ash/system_tray_delegate_chromeos.cc
@@ -238,6 +238,7 @@
   DBusThreadManager::Get()->GetSessionManagerClient()->AddObserver(this);
 
   input_method::InputMethodManager::Get()->AddObserver(this);
+  input_method::InputMethodManager::Get()->AddImeMenuObserver(this);
   ui::ime::InputMethodMenuManager::GetInstance()->AddObserver(this);
 
   g_browser_process->platform_part()->GetSystemClock()->AddObserver(this);
@@ -1294,6 +1295,16 @@
                     OnShutdownPolicyChanged(reboot_on_shutdown));
 }
 
+void SystemTrayDelegateChromeOS::ImeMenuActivationChanged(bool is_active) {
+  GetSystemTrayNotifier()->NotifyRefreshIMEMenu(is_active);
+}
+
+void SystemTrayDelegateChromeOS::ImeMenuListChanged() {}
+
+void SystemTrayDelegateChromeOS::ImeMenuItemsChanged(
+    const std::string& engine_id,
+    const std::vector<input_method::InputMethodManager::MenuItem>& items) {}
+
 const base::string16
 SystemTrayDelegateChromeOS::GetLegacySupervisedUserMessage() const {
   std::string user_manager_name = GetSupervisedUserManager();
diff --git a/chrome/browser/ui/ash/system_tray_delegate_chromeos.h b/chrome/browser/ui/ash/system_tray_delegate_chromeos.h
index 726ede8..a60e6e9 100644
--- a/chrome/browser/ui/ash/system_tray_delegate_chromeos.h
+++ b/chrome/browser/ui/ash/system_tray_delegate_chromeos.h
@@ -68,7 +68,8 @@
       public user_manager::UserManager::UserSessionStateObserver,
       public SupervisedUserServiceObserver,
       public ShutdownPolicyHandler::Delegate,
-      public system::SystemClockObserver {
+      public system::SystemClockObserver,
+      public input_method::InputMethodManager::ImeMenuObserver {
  public:
   SystemTrayDelegateChromeOS();
 
@@ -269,6 +270,14 @@
   // Overridden from ShutdownPolicyObserver::Delegate.
   void OnShutdownPolicyChanged(bool reboot_on_shutdown) override;
 
+  // input_method::InputMethodManager::ImeMenuObserver:
+  void ImeMenuActivationChanged(bool is_active) override;
+  void ImeMenuListChanged() override;
+  void ImeMenuItemsChanged(
+      const std::string& engine_id,
+      const std::vector<input_method::InputMethodManager::MenuItem>& items)
+      override;
+
   // helper methods used by GetSupervisedUserMessage.
   const base::string16 GetLegacySupervisedUserMessage() const;
   const base::string16 GetChildUserMessage() const;
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 0a63f037..a9d437f0 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
@@ -6,6 +6,7 @@
 
 #include <string>
 
+#include "base/command_line.h"
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
 #include "chrome/browser/browser_process.h"
@@ -28,6 +29,7 @@
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/signin/easy_unlock_service.h"
 #include "chrome/browser/ui/webui/chromeos/ui_account_tweaks.h"
+#include "chromeos/chromeos_switches.h"
 #include "components/user_manager/user.h"
 #include "components/user_manager/user_manager.h"
 #include "ui/chromeos/strings/grit/ui_chromeos_strings.h"
@@ -91,6 +93,16 @@
     {"delayBeforeClickVeryLong", IDS_SETTINGS_DELAY_BEFORE_CLICK_VERY_LONG},
     {"onScreenKeyboardLabel", IDS_SETTINGS_ON_SCREEN_KEYBOARD_LABEL},
     {"a11yExplanation", IDS_SETTINGS_ACCESSIBILITY_EXPLANATION},
+    {"caretHighlightLabel",
+     IDS_OPTIONS_SETTINGS_ACCESSIBILITY_CARET_HIGHLIGHT_DESCRIPTION},
+    {"cursorHighlightLabel",
+     IDS_OPTIONS_SETTINGS_ACCESSIBILITY_CURSOR_HIGHLIGHT_DESCRIPTION},
+    {"focusHighlightLabel",
+     IDS_OPTIONS_SETTINGS_ACCESSIBILITY_FOCUS_HIGHLIGHT_DESCRIPTION},
+    {"selectToSpeakLabel",
+     IDS_OPTIONS_SETTINGS_ACCESSIBILITY_SELECT_TO_SPEAK_DESCRIPTION},
+    {"switchAccessLabel",
+     IDS_OPTIONS_SETTINGS_ACCESSIBILITY_SWITCH_ACCESS_DESCRIPTION},
 #endif
   };
   AddLocalizedStringsBulk(html_source, localized_strings,
@@ -99,6 +111,10 @@
 #if defined(OS_CHROMEOS)
   html_source->AddString("a11yLearnMoreUrl",
                          chrome::kChromeAccessibilityHelpURL);
+
+  html_source->AddBoolean("showExperimentalA11yFeatures",
+      base::CommandLine::ForCurrentProcess()->HasSwitch(
+          chromeos::switches::kEnableExperimentalAccessibilityFeatures));
 #endif
 }
 
diff --git a/chrome/installer/setup/installer_metrics.cc b/chrome/installer/setup/installer_metrics.cc
index 8e5f0443..5bf860c 100644
--- a/chrome/installer/setup/installer_metrics.cc
+++ b/chrome/installer/setup/installer_metrics.cc
@@ -8,29 +8,29 @@
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/metrics/histogram_base.h"
-#include "base/metrics/histogram_persistence.h"
+#include "base/metrics/persistent_histogram_allocator.h"
 #include "base/metrics/persistent_memory_allocator.h"
 #include "chrome/installer/util/util_constants.h"
 
 namespace installer {
 
 void BeginPersistentHistogramStorage() {
-  base::SetPersistentHistogramMemoryAllocator(
-      new base::LocalPersistentMemoryAllocator(
-          1 << 20, 0,  // 1 MiB
-          installer::kSetupHistogramAllocatorName));
-  base::GetPersistentHistogramMemoryAllocator()->CreateTrackingHistograms(
+  base::PersistentHistogramAllocator::CreateGlobalAllocatorOnLocalMemory(
+      1 << 20,  // 1 MiB
+      0,        // No identifier.
       installer::kSetupHistogramAllocatorName);
+  base::PersistentHistogramAllocator::GetGlobalAllocator()
+      ->CreateTrackingHistograms(installer::kSetupHistogramAllocatorName);
 }
 
 void EndPersistentHistogramStorage(const base::FilePath& target_path) {
+  base::PersistentHistogramAllocator* allocator =
+      base::PersistentHistogramAllocator::GetGlobalAllocator();
+  allocator->UpdateTrackingHistograms();
+
   // For atomicity, first write to a temporary file and then rename it.
   // The ImportantFileWriter would be good for this except it supports only
   // std::string for its data.
-  base::PersistentMemoryAllocator* allocator =
-      base::GetPersistentHistogramMemoryAllocator();
-  allocator->UpdateTrackingHistograms();
-
   base::FilePath file_path = target_path
       .AppendASCII(allocator->Name())
       .AddExtension(L".pma");
diff --git a/chrome/renderer/worker_content_settings_client_proxy.cc b/chrome/renderer/worker_content_settings_client_proxy.cc
index ce38f34..a98867c 100644
--- a/chrome/renderer/worker_content_settings_client_proxy.cc
+++ b/chrome/renderer/worker_content_settings_client_proxy.cc
@@ -31,20 +31,6 @@
 
 WorkerContentSettingsClientProxy::~WorkerContentSettingsClientProxy() {}
 
-bool WorkerContentSettingsClientProxy::allowDatabase(
-    const blink::WebString& name,
-    const blink::WebString& display_name,
-    unsigned long estimated_size) {
-  if (is_unique_origin_)
-    return false;
-
-  bool result = false;
-  sync_message_filter_->Send(new ChromeViewHostMsg_AllowDatabase(
-      routing_id_, document_origin_url_, top_frame_origin_url_,
-      name, display_name, &result));
-  return result;
-}
-
 bool WorkerContentSettingsClientProxy::requestFileSystemAccessSync() {
   if (is_unique_origin_)
     return false;
diff --git a/chrome/renderer/worker_content_settings_client_proxy.h b/chrome/renderer/worker_content_settings_client_proxy.h
index 1a9739d6..1e843a23 100644
--- a/chrome/renderer/worker_content_settings_client_proxy.h
+++ b/chrome/renderer/worker_content_settings_client_proxy.h
@@ -32,9 +32,6 @@
   ~WorkerContentSettingsClientProxy() override;
 
   // WebWorkerContentSettingsClientProxy overrides.
-  bool allowDatabase(const blink::WebString& name,
-                     const blink::WebString& display_name,
-                     unsigned long estimated_size) override;
   bool requestFileSystemAccessSync() override;
   bool allowIndexedDB(const blink::WebString& name) override;
 
diff --git a/chrome/test/data/autofill/heuristics/input/140_checkout_nike.com.html b/chrome/test/data/autofill/heuristics/input/140_checkout_nike.com.html
new file mode 100644
index 0000000..99f965d8
--- /dev/null
+++ b/chrome/test/data/autofill/heuristics/input/140_checkout_nike.com.html
@@ -0,0 +1,613 @@
+<form id="shippingForm" name="shippingForm" action="https://secure-store.nike.com/us/checkout/html/shipping.jsp?_DARGS=/us/checkout/common/shipping.jsp.shippingForm" class="panel formValidation" method="post" novalidate=""><input name="_dyncharset" value="UTF-8" type="hidden"><input name="_dynSessConf" value="-8061397768254292283" type="hidden"><input id="copyFrom" name="/atg/commerce/order/purchase/ShippingGroupFormHandler.copyfrom" value="" type="hidden"><input name="_D:/atg/commerce/order/purchase/ShippingGroupFormHandler.copyfrom" value=" " type="hidden"><input id="copyAddress" name="/atg/commerce/order/purchase/ShippingGroupFormHandler.copyAddress" value="" type="hidden"><input name="_D:/atg/commerce/order/purchase/ShippingGroupFormHandler.copyAddress" value=" " type="hidden"><input id="s_copyShipToBillingAddress" name="copyShipToBillingAddress" value="true" type="hidden"><input name="_D:copyShipToBillingAddress" value=" " type="hidden"><input id="saveShipAddressToProfile" name="/atg/commerce/order/purchase/ShippingGroupFormHandler.saveShipAddressToProfile" value="false" type="hidden"><input name="_D:/atg/commerce/order/purchase/ShippingGroupFormHandler.saveShipAddressToProfile" value=" " type="hidden"><input id="s_firstName" name="/atg/commerce/order/purchase/ShippingGroupFormHandler.shippingGroup.shippingAddress.firstName" value="" class="js-firstName_s" type="hidden"><input name="_D:/atg/commerce/order/purchase/ShippingGroupFormHandler.shippingGroup.shippingAddress.firstName" value=" " type="hidden"><input id="s_lastName" name="/atg/commerce/order/purchase/ShippingGroupFormHandler.shippingGroup.shippingAddress.lastName" value="" class="js-lastName_s" type="hidden"><input name="_D:/atg/commerce/order/purchase/ShippingGroupFormHandler.shippingGroup.shippingAddress.lastName" value=" " type="hidden"><input id="s_altFirstName" name="/atg/commerce/order/purchase/ShippingGroupFormHandler.shippingGroup.shippingAddress.altFirstName" value="" class="js-altFirstName_s" type="hidden"><input name="_D:/atg/commerce/order/purchase/ShippingGroupFormHandler.shippingGroup.shippingAddress.altFirstName" value=" " type="hidden"><input id="s_altLastName" name="/atg/commerce/order/purchase/ShippingGroupFormHandler.shippingGroup.shippingAddress.altLastName" value="" class="js-altLastName_s" type="hidden"><input name="_D:/atg/commerce/order/purchase/ShippingGroupFormHandler.shippingGroup.shippingAddress.altLastName" value=" " type="hidden"><input id="s_zipCode" name="/atg/commerce/order/purchase/ShippingGroupFormHandler.shippingGroup.shippingAddress.postalCode" value="" class="js-zipCode_s" type="hidden"><input name="_D:/atg/commerce/order/purchase/ShippingGroupFormHandler.shippingGroup.shippingAddress.postalCode" value=" " type="hidden"><input id="s_address1" name="/atg/commerce/order/purchase/ShippingGroupFormHandler.shippingGroup.shippingAddress.address1" value="" class="js-address1_s" type="hidden"><input name="_D:/atg/commerce/order/purchase/ShippingGroupFormHandler.shippingGroup.shippingAddress.address1" value=" " type="hidden"><input id="s_address2" name="/atg/commerce/order/purchase/ShippingGroupFormHandler.shippingGroup.shippingAddress.address2" value="" class="js-address2_s" type="hidden"><input name="_D:/atg/commerce/order/purchase/ShippingGroupFormHandler.shippingGroup.shippingAddress.address2" value=" " type="hidden"><input id="s_address3" name="/atg/commerce/order/purchase/ShippingGroupFormHandler.shippingGroup.shippingAddress.address3" value="" class="js-address3_s" type="hidden"><input name="_D:/atg/commerce/order/purchase/ShippingGroupFormHandler.shippingGroup.shippingAddress.address3" value=" " type="hidden"><input id="s_city" name="/atg/commerce/order/purchase/ShippingGroupFormHandler.shippingGroup.shippingAddress.city" value="" class="js-city_s" type="hidden"><input name="_D:/atg/commerce/order/purchase/ShippingGroupFormHandler.shippingGroup.shippingAddress.city" value=" " type="hidden"><input id="s_county" name="/atg/commerce/order/purchase/ShippingGroupFormHandler.shippingGroup.shippingAddress.county" value="" class="js-county_s" type="hidden"><input name="_D:/atg/commerce/order/purchase/ShippingGroupFormHandler.shippingGroup.shippingAddress.county" value=" " type="hidden"><input id="s_state" name="/atg/commerce/order/purchase/ShippingGroupFormHandler.shippingGroup.shippingAddress.state" value="" class="js-state_s" type="hidden"><input name="_D:/atg/commerce/order/purchase/ShippingGroupFormHandler.shippingGroup.shippingAddress.state" value=" " type="hidden"><input id="s_companyName" name="/atg/commerce/order/purchase/ShippingGroupFormHandler.shippingGroup.shippingAddress.companyName" value="" class="js-companyName_s" type="hidden"><input name="_D:/atg/commerce/order/purchase/ShippingGroupFormHandler.shippingGroup.shippingAddress.companyName" value=" " type="hidden"><input id="s_accessPointField" name="/atg/commerce/order/purchase/ShippingGroupFormHandler.accessPointId" value="" class="js-accessPoint_s" type="hidden"><input name="_D:/atg/commerce/order/purchase/ShippingGroupFormHandler.accessPointId" value=" " type="hidden"><input id="s_cppField" name="/atg/commerce/order/purchase/ShippingGroupFormHandler.cppId" value="" class="js-cpp_s" type="hidden"><input name="_D:/atg/commerce/order/purchase/ShippingGroupFormHandler.cppId" value=" " type="hidden"><input id="s_shippingAddressValidationCode" name="/atg/commerce/order/purchase/ShippingGroupFormHandler.shippingGroup.validatedCode" value="0" class="js-shippingAddressValidationCode_s" type="hidden"><input name="_D:/atg/commerce/order/purchase/ShippingGroupFormHandler.shippingGroup.validatedCode" value=" " type="hidden"><input id="s_phoneNumber" name="/atg/commerce/order/purchase/ShippingGroupFormHandler.shippingGroup.shippingAddress.phoneNumber" value="" class="js-phoneNumber_s" type="hidden"><input name="_D:/atg/commerce/order/purchase/ShippingGroupFormHandler.shippingGroup.shippingAddress.phoneNumber" value=" " type="hidden"><input id="s_faxNumber" name="/atg/commerce/order/purchase/ShippingGroupFormHandler.shippingGroup.shippingAddress.faxNumber" value="" class="js-faxNumber_s" type="hidden"><input name="_D:/atg/commerce/order/purchase/ShippingGroupFormHandler.shippingGroup.shippingAddress.faxNumber" value=" " type="hidden"><input id="s_email" name="/atg/commerce/order/purchase/ShippingGroupFormHandler.shippingGroup.shippingAddress.email" value="" class="js-email_s" type="hidden"><input name="_D:/atg/commerce/order/purchase/ShippingGroupFormHandler.shippingGroup.shippingAddress.email" value=" " type="hidden"><input name="/atg/commerce/order/purchase/ShippingGroupFormHandler.captureFapiao" value="false" type="hidden"><input name="_D:/atg/commerce/order/purchase/ShippingGroupFormHandler.captureFapiao" value=" " type="hidden"><input name="/atg/commerce/order/purchase/ShippingGroupFormHandler.capturePreferredDeliveryDay" value="false" type="hidden"><input name="_D:/atg/commerce/order/purchase/ShippingGroupFormHandler.capturePreferredDeliveryDay" value=" " type="hidden"><!-- Left column and cart items -->
+  <div id="ch4_checkoutItems">
+    <div id="ch4_checkoutHeadingOpen" class="ch4_uppercase">1. SHIPPING</div>
+    <div id="ch4_checkoutShippingForm">
+
+      <div class="shippingSection">
+
+  <input type="hidden" id="hasSavedAddresses" name="hasSavedAddresses" value="false">
+      <div class="ch4_formAddressType ch4_uppercase">
+        <input id="singleAddress" type="radio" name="selectAddressType" class="ch4_formAddressTypeRadio js-addressType" value="singleAddress" checked="" title="overall type: UNKNOWN_TYPE
+    server type: NO_SERVER_DATA
+    heuristic type: UNKNOWN_TYPE
+    label: Home/Office Address
+    parseable name: selectAddressType
+    field signature: 3604897261
+    form signature: 17034931100313024041">
+            <label for="singleAddress">
+              Home/Office Address</label>
+          </div>
+    <div class="ch4_formAddressType ch4_uppercase">
+        <input id="militaryAddress" type="radio" name="selectAddressType" class="ch4_formAddressTypeRadio js-addressType" value="militaryAddress" title="overall type: UNKNOWN_TYPE
+    server type: NO_SERVER_DATA
+    heuristic type: UNKNOWN_TYPE
+    label: APO/FPO
+    parseable name: selectAddressType
+    field signature: 3604897261
+    form signature: 17034931100313024041">
+            <label for="militaryAddress">
+              APO/FPO</label>
+            <a href="#" class="ch4_help"><div class="ch4_toolTip" style="display: none;"><div class="ch4_toolTipArrow"></div>Nike proudly supports our service men and women overseas! Choose APO/FPO if you are shipping to someone at a Military Post Office. Note: NIKEiD products excluded.</div></a>
+          </div>
+    <div class="singleAddress" style="display:block">
+        <!-- intl shopping include -->
+
+<!-- intl shopping studio flag = false -->
+<div class="ch4_formRow">
+    <div class="ch4_formLabel">First Name&nbsp;<span class="requiredColor">*</span></div>
+    <div class="ch4_formField">
+      <input name="fname" id="fname" maxlength="35" type="text" class="ch4_formTextField js-firstName ch4_formTextFieldError" required="required" data-error-invalid="You have entered an invalid character." data-error-blacklist="Blacklisted character" data-error-required="Please enter your first name." data-validate="name" value="" title="overall type: NAME_FIRST
+    server type: NAME_FIRST
+    heuristic type: NAME_FIRST
+    label: First Name *
+    parseable name: fname
+    field signature: 2852189818
+    form signature: 17034931100313024041" data-msg="Please enter your first name."><div class="ch4_errorTip" style="left: 202px; top: 0px;"><div class="ch4_errorTipTipLeft">&nbsp;</div>Please enter your first name.</div>
+    </div>
+  </div>
+  <div class="ch4_formRow">
+    <div class="ch4_formLabel">Last Name&nbsp;<span class="requiredColor">*</span></div>
+    <div class="ch4_formField">
+      <input name="lname" id="lname" maxlength="35" type="text" class="ch4_formTextField js-lastName" required="required" data-error-invalid="You have entered an invalid character." data-error-blacklist="Blacklisted character" data-error-required="Please enter your last name." data-validate="name" value="" title="overall type: NAME_LAST
+    server type: NAME_LAST
+    heuristic type: NAME_LAST
+    label: Last Name *
+    parseable name: lname
+    field signature: 3030290319
+    form signature: 17034931100313024041">
+    </div>
+  </div>
+<div class="ch4_formRow">
+        <div class="ch4_formLabel">Address&nbsp;<span class="requiredColor">*</span></div>
+        <div class="ch4_formField">
+          <input name="address1Field" id="address1Field" maxlength="35" type="text" class="ch4_formTextField js-address1" value="" title="overall type: ADDRESS_HOME_LINE1
+    server type: ADDRESS_HOME_LINE1
+    heuristic type: ADDRESS_HOME_LINE1
+    label: Address *
+    parseable name: address1Field
+    field signature: 3711209280
+    form signature: 17034931100313024041"><br>
+        </div>
+        <div class="ch4_formExtraInfoAPO">
+                  We do not ship to P.O. boxes</div>
+              </div>
+    <div class="ch4_formRow">
+    <div class="ch4_formLabel">&nbsp;</div>
+        <div class="ch4_formField">
+          <input name="address2Field" id="address2Field" maxlength="35" type="text" class="ch4_formTextField js-address2" value="" title="overall type: ADDRESS_HOME_LINE2
+    server type: ADDRESS_HOME_LINE2
+    heuristic type: ADDRESS_HOME_LINE2
+    label: 1. SHIPPING
+    parseable name: address2Field
+    field signature: 3200000380
+    form signature: 17034931100313024041"><br>
+        </div>
+      </div>
+
+  <div id="hideCity" class="ch4_formRow">
+        <div class="ch4_formLabel">City&nbsp;<span class="requiredColor">*</span></div>
+        <div class="ch4_formField">
+          <input name="city" id="singleCity" maxlength="35" type="text" class="ch4_formTextField js-city" value="" title="overall type: ADDRESS_HOME_CITY
+    server type: ADDRESS_HOME_CITY
+    heuristic type: ADDRESS_HOME_CITY
+    label: City *
+    parseable name: city
+    field signature: 2098554694
+    form signature: 17034931100313024041">
+        </div>
+      </div>
+
+      <div id="hideState" class="ch4_formRow">
+        <div class="ch4_formLabel">State&nbsp;<span class="requiredColor">*</span></div>
+        <div class="ch4_formField">
+          <div class="style-select-wrapper">
+        <select name="singleState" id="singleState" class="js-state" data-update="js-state_s" title="overall type: ADDRESS_HOME_STATE
+    server type: ADDRESS_HOME_STATE
+    heuristic type: ADDRESS_HOME_STATE
+    label: State *
+    parseable name: singleState
+    field signature: 1160507728
+    form signature: 17034931100313024041">
+          <option value="">Select State</option>
+          <option value="AL">
+                 Alabama</option>
+            <option value="AK">
+                 Alaska</option>
+            <option value="AZ">
+                 Arizona</option>
+            <option value="AR">
+                 Arkansas</option>
+            <option value="CA">
+                 California</option>
+            <option value="CO">
+                 Colorado</option>
+            <option value="CT">
+                 Connecticut</option>
+            <option value="DE">
+                 Delaware</option>
+            <option value="DC">
+                 District of Columbia</option>
+            <option value="FL">
+                 Florida</option>
+            <option value="GA">
+                 Georgia</option>
+            <option value="HI">
+                 Hawaii</option>
+            <option value="ID">
+                 Idaho</option>
+            <option value="IL">
+                 Illinois</option>
+            <option value="IN">
+                 Indiana</option>
+            <option value="IA">
+                 Iowa</option>
+            <option value="KS">
+                 Kansas</option>
+            <option value="KY">
+                 Kentucky</option>
+            <option value="LA">
+                 Louisiana</option>
+            <option value="ME">
+                 Maine</option>
+            <option value="MD">
+                 Maryland</option>
+            <option value="MA">
+                 Massachusetts</option>
+            <option value="MI">
+                 Michigan</option>
+            <option value="MN">
+                 Minnesota</option>
+            <option value="MS">
+                 Mississippi</option>
+            <option value="MO">
+                 Missouri</option>
+            <option value="MT">
+                 Montana</option>
+            <option value="NE">
+                 Nebraska</option>
+            <option value="NV">
+                 Nevada</option>
+            <option value="NH">
+                 New Hampshire</option>
+            <option value="NJ">
+                 New Jersey</option>
+            <option value="NM">
+                 New Mexico</option>
+            <option value="NY">
+                 New York</option>
+            <option value="NC">
+                 North Carolina</option>
+            <option value="ND">
+                 North Dakota</option>
+            <option value="OH">
+                 Ohio</option>
+            <option value="OK">
+                 Oklahoma</option>
+            <option value="OR">
+                 Oregon</option>
+            <option value="PA">
+                 Pennsylvania</option>
+            <option value="RI">
+                 Rhode Island</option>
+            <option value="SC">
+                 South Carolina</option>
+            <option value="SD">
+                 South Dakota</option>
+            <option value="TN">
+                 Tennessee</option>
+            <option value="TX">
+                 Texas</option>
+            <option value="UT">
+                 Utah</option>
+            <option value="VT">
+                 Vermont</option>
+            <option value="VA">
+                 Virginia</option>
+            <option value="WA">
+                 Washington</option>
+            <option value="WV">
+                 West Virginia</option>
+            <option value="WI">
+                 Wisconsin</option>
+            <option value="WY">
+                 Wyoming</option>
+            </select>
+        <div class="style-select"></div>
+      </div>
+</div>
+      </div>
+      <div class="ch4_formRow">
+        <div class="ch4_formLabel">ZIP Code&nbsp;<span class="requiredColor">*</span></div>
+        <div class="ch4_formField">
+          <input name="postalCodeField" id="postalCodeField" type="text" maxlength="10" class="ch4_formTextField js-zipCode" value="" title="overall type: ADDRESS_HOME_ZIP
+    server type: ADDRESS_HOME_ZIP
+    heuristic type: ADDRESS_HOME_ZIP
+    label: ZIP Code *
+    parseable name: postalCodeField
+    field signature: 1505678046
+    form signature: 17034931100313024041">
+        </div>
+      </div>
+      <input name="countryField" class="js-country" type="hidden" value="US">
+    </div>
+    <div class="militaryAddress" style="display:none">
+        <div class="ch4_formRow">
+    <div class="ch4_formLabel">First Name&nbsp;<span class="requiredColor">*</span></div>
+    <div class="ch4_formField">
+      <input name="fname" id="fname_apofpo" maxlength="35" type="text" class="ch4_formTextField js-firstName" required="required" data-error-invalid="You have entered an invalid character." data-error-blacklist="Blacklisted character" data-error-required="Please enter your first name." data-validate="name" value="" title="overall type: NAME_FIRST
+    server type: NAME_FIRST
+    heuristic type: NAME_FIRST
+    label: First Name *
+    parseable name: fname
+    field signature: 2852189818
+    form signature: 17034931100313024041">
+    </div>
+  </div>
+  <div class="ch4_formRow">
+    <div class="ch4_formLabel">Last Name&nbsp;<span class="requiredColor">*</span></div>
+    <div class="ch4_formField">
+      <input name="lname" id="lname_apofpo" maxlength="35" type="text" class="ch4_formTextField js-lastName" required="required" data-error-invalid="You have entered an invalid character." data-error-blacklist="Blacklisted character" data-error-required="Please enter your last name." data-validate="name" value="" title="overall type: NAME_LAST
+    server type: NAME_LAST
+    heuristic type: NAME_LAST
+    label: Last Name *
+    parseable name: lname
+    field signature: 3030290319
+    form signature: 17034931100313024041">
+    </div>
+  </div>
+<div class="ch4_formRow">
+    <div class="ch4_formLabel">Address&nbsp;<span class="requiredColor">*</span></div>
+    <div class="ch4_formField">
+      <input name="address1Field" id="address1Field_apofpo" maxlength="35" type="text" class="ch4_formTextField js-address1" value="" title="overall type: ADDRESS_HOME_LINE1
+    server type: ADDRESS_HOME_LINE1
+    heuristic type: ADDRESS_HOME_LINE1
+    label: Address *
+    parseable name: address1Field
+    field signature: 3711209280
+    form signature: 17034931100313024041"><br>
+    </div>
+  </div>
+
+  <div class="ch4_formExtraInfoAPO">
+    For Army, Navy, and Marines, enter your unit # and box #<br>
+    For ships, enter the ship name and hull #<br>
+    For Air Force, enter the PSC # and box #</div>
+
+  <div class="ch4_formRow">
+    <div class="ch4_formLabel">&nbsp;</div>
+    <div class="ch4_formField">
+      <input name="address2Field" id="address2Field_apofpo" maxlength="35" type="text" class="ch4_formTextField js-address2" value="" title="overall type: ADDRESS_HOME_LINE2
+    server type: ADDRESS_HOME_LINE2
+    heuristic type: ADDRESS_HOME_LINE2
+    label: Enter the military command or organization name if applicable
+    parseable name: address2Field
+    field signature: 3200000380
+    form signature: 17034931100313024041"><br>
+    </div>
+    <div class="ch4_formExtraInfoAPO">Enter the military command or organization name if applicable</div>
+  </div>
+
+  <div class="ch4_formRow">
+    <div class="ch4_formLabel">APO/FPO&nbsp;<span class="requiredColor">*</span></div>
+    <div class="ch4_formField">
+      <div class="style-select-wrapper">
+        <select name="apoCity" id="apoCity" class="js-city" data-update="js-city_s" title="overall type: ADDRESS_HOME_CITY
+    server type: NO_SERVER_DATA
+    heuristic type: ADDRESS_HOME_CITY
+    label: APO/FPO *
+    parseable name: apoCity
+    field signature: 1890694515
+    form signature: 17034931100313024041">
+          <option value="APO" selected="">Army Post Office</option>
+          <option value="FPO">Fleet Post Office</option>
+        </select>
+        <div class="style-select"></div>
+      </div>
+    </div>
+  </div>
+
+  <div class="ch4_formRow">
+    <div class="ch4_formLabel">Region&nbsp;<span class="requiredColor">*</span></div>
+    <div class="ch4_formField">
+      <div class="style-select-wrapper">
+        <select name="apoState" class="js-state" id="apoState" data-update="js-state_s" title="overall type: ADDRESS_HOME_STATE
+    server type: NO_SERVER_DATA
+    heuristic type: ADDRESS_HOME_STATE
+    label: Region *
+    parseable name: apoState
+    field signature: 505741244
+    form signature: 17034931100313024041">
+          <option value="AA" selected="">Armed Forces Americas</option>
+          <option value="AE">Armed Forces Europe</option>
+          <option value="AP">Armed Forces Pacific</option>
+        </select>
+        <div class="style-select"></div>
+      </div>
+    </div>
+  </div>
+
+  <div class="ch4_formRow">
+    <div class="ch4_formLabel">ZIP Code&nbsp;<span class="requiredColor">*</span></div>
+    <div class="ch4_formField">
+      <input name="postalCodeField" id="postalCodeField_apofpo" type="text" maxlength="10" class="ch4_formTextField js-zipCode" value="" title="overall type: ADDRESS_HOME_ZIP
+    server type: ADDRESS_HOME_ZIP
+    heuristic type: ADDRESS_HOME_ZIP
+    label: ZIP Code *
+    parseable name: postalCodeField
+    field signature: 1505678046
+    form signature: 17034931100313024041">
+    </div>
+  </div>
+
+  <input name="countryField" class="js-country" type="hidden" value="US">
+
+  </div>
+    <input type="hidden" id="idItemInCart" value="false">
+  <input type="hidden" id="sgid" value="SG1125902365">
+
+  <div class="marginTop">
+    </div>
+
+  <div class="marginTop">
+    <div class="js-shippingMethodDisplay singleAddress savedAddress " style="display:block">
+    <div class="shippingMethodTitle">
+      Select Shipping Method:
+      <span href="#" class="ch4_help " style="cursor: pointer; ': ''}">
+    <div class="ch4_toolTip" style="display: none;">
+      <div class="ch4_toolTipArrow"></div>
+      Shipping estimates don’t include weekends or holidays.&nbsp;<a href="http://help-en-us.nike.com/app/answers/detail/article/shipping-delivery/a_id/19279/p/3897" class="ch4_toolTipLink" target="_blank">See details</a>
+      </div>
+  </span>
+
+</div>
+    <div class="js-shippingMethodText" style="display:none">
+      <span class="eddDescription">Standard</span>
+  <span class="eddText">
+
+
+      (<span class="js-eddLabel" data-method="Ground Service">Arrives 2-4 Days</span>)&nbsp;
+    </span>
+  <span class="eddPrice"><span class="nike-orange">FREE</span></span>
+
+
+</div>
+    <div class="ch4_shippingMethodSelection js-shippingMethodSelection" style="display:block">
+        <div class="ch4_radioUnit cbrUnit js-radioUnit ch4_hideValid">
+              <input id="Ground_Service" type="radio" name="shippingMethod_single" class="js-shippingMethod ch4_hideValid " value="Ground Service" checked="checked" no-validate="" title="overall type: UNKNOWN_TYPE
+    server type: NO_SERVER_DATA
+    heuristic type: UNKNOWN_TYPE
+    label: Standard (Arrives 2-4 Days) FREE
+    parseable name: shippingMethod_single
+    field signature: 2416614014
+    form signature: 17034931100313024041">
+              <label for="Ground_Service">
+              </label>
+              <span class="shipping-label-text">
+                <span class="eddDescription">Standard</span>
+  <span class="eddText">
+
+
+      (<span class="js-eddLabel" data-method="Ground Service">Arrives 2-4 Days</span>)&nbsp;
+    </span>
+  <span class="eddPrice"><span class="nike-orange">FREE</span></span>
+
+
+</span>
+
+            </div>
+
+
+          <div class="ch4_radioUnit cbrUnit js-radioUnit ch4_hideValid">
+              <input id="Two_Day_Air" type="radio" name="shippingMethod_single" class="js-shippingMethod ch4_hideValid " value="Two Day Air" no-validate="" title="overall type: UNKNOWN_TYPE
+    server type: NO_SERVER_DATA
+    heuristic type: UNKNOWN_TYPE
+    label: Standard (Arrives 2-4 Days) FREE
+    parseable name: shippingMethod_single
+    field signature: 2416614014
+    form signature: 17034931100313024041">
+              <label for="Two_Day_Air">
+              </label>
+              <span class="shipping-label-text">
+                <span class="eddDescription">Two-Day</span>
+  <span class="eddText">
+
+
+      (<span class="js-eddLabel" data-method="Two Day Air">Arrives 2-3 Days</span>)&nbsp;
+    </span>
+  <span class="eddPrice">$15.00</span>
+
+
+</span>
+
+            </div>
+
+
+          <div class="ch4_radioUnit cbrUnit js-radioUnit ch4_hideValid">
+              <input id="Next_Day_Air" type="radio" name="shippingMethod_single" class="js-shippingMethod ch4_hideValid " value="Next Day Air" no-validate="" title="overall type: UNKNOWN_TYPE
+    server type: NO_SERVER_DATA
+    heuristic type: UNKNOWN_TYPE
+    label: Standard (Arrives 2-4 Days) FREE
+    parseable name: shippingMethod_single
+    field signature: 2416614014
+    form signature: 17034931100313024041">
+              <label for="Next_Day_Air">
+              </label>
+              <span class="shipping-label-text">
+                <span class="eddDescription">Next-Day</span>
+  <span class="eddText">
+
+
+      (<span class="js-eddLabel" data-method="Next Day Air">Arrives 1-2 Days</span>)&nbsp;
+    </span>
+  <span class="eddPrice">$25.00</span>
+
+
+</span>
+
+            </div>
+
+
+          </div>
+    </div>
+
+  <div class="js-militaryShipping militaryAddress" style="display:none">
+      <input type="hidden" class="js-shippingMethodDefault" value="Military Ground Service">
+      <div class="marginTop">
+        <div class="shippingMethodTitle">
+          Shipping Method:
+          <span href="#" class="ch4_help " style="cursor: pointer; ': ''}">
+    <div class="ch4_toolTip" style="display: none;">
+      <div class="ch4_toolTipArrow"></div>
+      Shipping estimates don’t include weekends or holidays.&nbsp;<a href="http://help-en-us.nike.com/app/answers/detail/article/shipping-delivery/a_id/19279/p/3897" class="ch4_toolTipLink" target="_blank">See details</a>
+      </div>
+  </span>
+
+</div>
+        <span class="eddDescription">Military Ground</span>
+  <span class="eddText">
+
+
+      (<span class="js-eddLabel" data-method="Military Ground Service">Arrives 30-45 Days</span>)&nbsp;
+    </span>
+  <span class="eddPrice"><span class="nike-orange">FREE</span></span>
+
+
+</div>
+    </div>
+  <input type="hidden" id="sgid" value="SG1125902365">
+  <input type="hidden" id="shipping_method" value="">
+
+
+  <div style="display:block" class="ch4_transitTimesMessage">Orders placed after 5pm EST begin processing the next business day.</div>
+    <div style="display:none" class="ch4_POBoxTransitTimesMessage">Orders placed after 10am EST begin processing the next business day.</div>
+  <input type="hidden" id="noPreference" name="preferredDeliveryDay" data-validate="radio" class="ch4_formShippingRadio js-formShippingRadio" value="noPreference" checked="">
+    </div>
+
+  </div>  <input id="isNewMember" name="/shared/UserAttributes.isNewMember" value="" type="hidden"><input name="_D:/shared/UserAttributes.isNewMember" value=" " type="hidden"><input id="emailOptIn" name="/shared/UserAttributes.emailOptIn" value="" type="hidden"><input name="_D:/shared/UserAttributes.emailOptIn" value=" " type="hidden"><div class="shippingSection removeInnerStyle">
+          <input id="isNewMember" name="/shared/UserAttributes.isNewMember" value="" type="hidden"><input name="_D:/shared/UserAttributes.isNewMember" value=" " type="hidden"><input id="emailOptIn" name="/shared/UserAttributes.emailOptIn" value="" type="hidden"><input name="_D:/shared/UserAttributes.emailOptIn" value=" " type="hidden"><div id="newMemberSection" class="ch4_formRow" style="clear:both;">
+
+          <input type="checkbox" id="ch4_becomeMember" name="becomeMember" class="ch4_formCheckBox revealOnCheck" title="overall type: UNKNOWN_TYPE
+    server type: NO_SERVER_DATA
+    heuristic type: UNKNOWN_TYPE
+    label: JOIN NIKE+ FOR FREE SHIPPING ON EVERY ORDER, EVERY TIME.
+    parseable name: becomeMember
+    field signature: 2079103496
+    form signature: 17034931100313024041">
+          <label for="ch4_becomeMember">JOIN NIKE+ FOR FREE SHIPPING ON EVERY ORDER, EVERY TIME.</label>
+          <div class="ch4_formRow">ALREADY HAVE A NIKE+ ACCOUNT?&nbsp; <a href="https://secure-store.nike.com/us/checkout/html/checkout_login.jsp">SIGN IN</a></div>
+            </div>
+
+        <div class="becomeMemberDiv" style="display:none;">
+
+          <div class="ch4_formRow">
+            <div class="ch4_formLabel">Email&nbsp;<span class="requiredColor">*</span></div>
+            <div class="ch4_formField"><input type="text" class="ch4_formTextField" name="reqEmail" id="reqEmail" maxlength="50" title="overall type: EMAIL_ADDRESS
+    server type: EMAIL_ADDRESS
+    heuristic type: EMAIL_ADDRESS
+    label: Email *
+    parseable name: reqEmail
+    field signature: 1897379167
+    form signature: 17034931100313024041"></div>
+          </div>
+
+          <div class="ch4_formRow reqPassword">
+            <div class="ch4_formLabel">Password&nbsp;<span class="requiredColor">*</span></div>
+            <div class="ch4_formField"><input id="reqPassword" title="overall type: PASSWORD
+    server type: PASSWORD
+    heuristic type: UNKNOWN_TYPE
+    label: Password *
+    parseable name: reqPassword
+    field signature: 3606218395
+    form signature: 17034931100313024041" class="ch4_formTextField" maxlength="36" type="password" onfocus="select()" name="reqPassword"></div>
+          </div>
+
+          <div class="ch4_formRow">
+            <div class="ch4_formLabel">Date of Birth&nbsp;<span class="requiredColor">*</span></div>
+            <div class="ch4_formField"><div class="style-select-wrapper monthDob-wrapper">
+            <select id="monthDob" name="monthDob" class="monthDob" title="overall type: UNKNOWN_TYPE
+    server type: NO_SERVER_DATA
+    heuristic type: UNKNOWN_TYPE
+    label: Date of Birth *
+    parseable name: monthDob
+    field signature: 3353643203
+    form signature: 17034931100313024041">
+          <option value="">MM</option>
+        <option value="1">1</option><option value="2">2</option><option value="3">3</option><option value="4">4</option><option value="5">5</option><option value="6">6</option><option value="7">7</option><option value="8">8</option><option value="9">9</option><option value="10">10</option><option value="11">11</option><option value="12">12</option></select>
+            <div class="style-select"></div>
+        </div>
+    <div class="style-select-wrapper dayDob-wrapper">
+            <select id="dayDob" name="dayDob" class="dayDob" title="overall type: UNKNOWN_TYPE
+    server type: NO_SERVER_DATA
+    heuristic type: UNKNOWN_TYPE
+    label: Date of Birth *
+    parseable name: dayDob
+    field signature: 2079150250
+    form signature: 17034931100313024041">
+          <option value="">DD</option>
+        <option value="1">1</option><option value="2">2</option><option value="3">3</option><option value="4">4</option><option value="5">5</option><option value="6">6</option><option value="7">7</option><option value="8">8</option><option value="9">9</option><option value="10">10</option><option value="11">11</option><option value="12">12</option><option value="13">13</option><option value="14">14</option><option value="15">15</option><option value="16">16</option><option value="17">17</option><option value="18">18</option><option value="19">19</option><option value="20">20</option><option value="21">21</option><option value="22">22</option><option value="23">23</option><option value="24">24</option><option value="25">25</option><option value="26">26</option><option value="27">27</option><option value="28">28</option><option value="29">29</option><option value="30">30</option><option value="31">31</option></select>
+            <div class="style-select"></div>
+        </div>
+  <div class="style-select-wrapper yearDob-wrapper">
+    <select id="yearDob" name="yearDob" class="yearDob" title="overall type: UNKNOWN_TYPE
+    server type: NO_SERVER_DATA
+    heuristic type: UNKNOWN_TYPE
+    label: Date of Birth *
+    parseable name: yearDob
+    field signature: 2918622286
+    form signature: 17034931100313024041">
+      <option value="">YYYY</option>
+      <option id="currentYear" value="2016">2016</option>
+    <option value="2015">2015</option><option value="2014">2014</option><option value="2013">2013</option><option value="2012">2012</option><option value="2011">2011</option><option value="2010">2010</option><option value="2009">2009</option><option value="2008">2008</option><option value="2007">2007</option><option value="2006">2006</option><option value="2005">2005</option><option value="2004">2004</option><option value="2003">2003</option><option value="2002">2002</option><option value="2001">2001</option><option value="2000">2000</option><option value="1999">1999</option><option value="1998">1998</option><option value="1997">1997</option><option value="1996">1996</option><option value="1995">1995</option><option value="1994">1994</option><option value="1993">1993</option><option value="1992">1992</option><option value="1991">1991</option><option value="1990">1990</option><option value="1989">1989</option><option value="1988">1988</option><option value="1987">1987</option><option value="1986">1986</option><option value="1985">1985</option><option value="1984">1984</option><option value="1983">1983</option><option value="1982">1982</option><option value="1981">1981</option><option value="1980">1980</option><option value="1979">1979</option><option value="1978">1978</option><option value="1977">1977</option><option value="1976">1976</option><option value="1975">1975</option><option value="1974">1974</option><option value="1973">1973</option><option value="1972">1972</option><option value="1971">1971</option><option value="1970">1970</option><option value="1969">1969</option><option value="1968">1968</option><option value="1967">1967</option><option value="1966">1966</option><option value="1965">1965</option><option value="1964">1964</option><option value="1963">1963</option><option value="1962">1962</option><option value="1961">1961</option><option value="1960">1960</option><option value="1959">1959</option><option value="1958">1958</option><option value="1957">1957</option><option value="1956">1956</option><option value="1955">1955</option><option value="1954">1954</option><option value="1953">1953</option><option value="1952">1952</option><option value="1951">1951</option><option value="1950">1950</option><option value="1949">1949</option><option value="1948">1948</option><option value="1947">1947</option><option value="1946">1946</option><option value="1945">1945</option><option value="1944">1944</option><option value="1943">1943</option><option value="1942">1942</option><option value="1941">1941</option><option value="1940">1940</option><option value="1939">1939</option><option value="1938">1938</option><option value="1937">1937</option><option value="1936">1936</option><option value="1935">1935</option><option value="1934">1934</option><option value="1933">1933</option><option value="1932">1932</option><option value="1931">1931</option><option value="1930">1930</option><option value="1929">1929</option><option value="1928">1928</option><option value="1927">1927</option><option value="1926">1926</option><option value="1925">1925</option><option value="1924">1924</option><option value="1923">1923</option><option value="1922">1922</option><option value="1921">1921</option><option value="1920">1920</option><option value="1919">1919</option><option value="1918">1918</option><option value="1917">1917</option></select>
+    <div class="style-select"></div>
+</div>
+
+</div>
+          </div>
+
+          <div class="ch4_formRow">
+            <div class="ch4_formLabel ch4_uppercase">Gender&nbsp;<span class="requiredColor">*</span></div>
+            <div class="ch4_formField ch4_genderText">
+              <input id="genderMale" type="radio" name="gender" value="male" class="ch4_formRadio" title="overall type: UNKNOWN_TYPE
+    server type: NO_SERVER_DATA
+    heuristic type: UNKNOWN_TYPE
+    label: MALE
+    parseable name: gender
+    field signature: 570340743
+    form signature: 17034931100313024041"><label for="genderMale">MALE</label>
+              <input id="genderFemale" type="radio" name="gender" value="female" class="ch4_formRadio" style="margin-left:10px;" title="overall type: UNKNOWN_TYPE
+    server type: NO_SERVER_DATA
+    heuristic type: UNKNOWN_TYPE
+    label: FEMALE
+    parseable name: gender
+    field signature: 570340743
+    form signature: 17034931100313024041"><label for="genderFemale">FEMALE</label>
+            </div>
+          </div>
+
+          <div id="ch4_formCheckBoxMember">
+            <input class="ch4_formCheckBox" id="receiveNikeOffers" name="receiveNikeOffers" type="checkbox" checked="checked" title="overall type: UNKNOWN_TYPE
+    server type: NO_SERVER_DATA
+    heuristic type: UNKNOWN_TYPE
+    label: I would like to be the first to hear about new products, innovations and exclusive offers.
+    parseable name: receiveNikeOffers
+    field signature: 3715053362
+    form signature: 17034931100313024041">
+                <input id="optinId" name="optinId" value="1420C" type="hidden">
+              <label for="receiveNikeOffers">I would like to be the first to hear about new products, innovations and exclusive offers.</label>
+          </div>
+
+        </div>
+
+     </div>  <input id="apoFlag" name="apoFlag" type="hidden" value="false">
+  <input id="langLocale" name="langLocale" type="hidden" value="en_US">
+  <input id="country" name="country" type="hidden" value="US">
+  <input type="hidden" id="route" name="route" value="html">
+  <input name="/atg/commerce/order/purchase/ShippingGroupFormHandler.applyShippingInfoErrorURL" value="shippingPageURL" type="hidden"><input name="_D:/atg/commerce/order/purchase/ShippingGroupFormHandler.applyShippingInfoErrorURL" value=" " type="hidden"><input type="hidden" id="returnURL" name="returnURL" value="http://store.nike.com/us/en_us/pd/lunarepic-flyknit-running-shoe/pid-10871565/pgid-10940948">
+  <input name="/atg/commerce/order/purchase/ShippingGroupFormHandler.applyShippingInfoSuccessURL" value="billingPageURL" type="hidden"><input name="_D:/atg/commerce/order/purchase/ShippingGroupFormHandler.applyShippingInfoSuccessURL" value=" " type="hidden"><input name="/atg/commerce/order/purchase/ShippingGroupFormHandler.applyShippingInfo" value="true" type="hidden"><input name="_D:/atg/commerce/order/purchase/ShippingGroupFormHandler.applyShippingInfo" value=" " type="hidden"><div class="ch4_formButtonRow " id="">
+        <span class="requiredLabel"><span class="requiredColor">*</span>&nbsp;Required Fields</span>
+        <input type="button" id="shippingSubmit" name="shipSubmit" value="NEXT STEP" class="ch4_btn ch4_btnOrange ch4_btnDropShadow" style="min-width:100px;">
+      </div>
+    </div>
+  </div>
+
+  <input name="_DARGS" value="/us/checkout/common/shipping.jsp.shippingForm" type="hidden"></form>
diff --git a/chrome/test/data/autofill/heuristics/output/140_checkout_nike.com.out b/chrome/test/data/autofill/heuristics/output/140_checkout_nike.com.out
new file mode 100644
index 0000000..d63b1247
--- /dev/null
+++ b/chrome/test/data/autofill/heuristics/output/140_checkout_nike.com.out
@@ -0,0 +1,28 @@
+UNKNOWN_TYPE | selectAddressType | Home/Office Address | singleAddress | selectAddressType_1-default
+UNKNOWN_TYPE | selectAddressType | APO/FPO | militaryAddress | selectAddressType_1-default
+NAME_FIRST | fname | First Name * |  | selectAddressType_1-default
+NAME_LAST | lname | Last Name * |  | selectAddressType_1-default
+ADDRESS_HOME_LINE1 | address1Field | Address * |  | selectAddressType_1-default
+ADDRESS_HOME_LINE2 | address2Field | 1. SHIPPING |  | selectAddressType_1-default
+ADDRESS_HOME_CITY | city | City * |  | selectAddressType_1-default
+ADDRESS_HOME_STATE | singleState | State * |  | selectAddressType_1-default
+ADDRESS_HOME_ZIP | postalCodeField | ZIP Code * |  | selectAddressType_1-default
+NAME_FIRST | fname | First Name * |  | selectAddressType_1-default
+NAME_LAST | lname | Last Name * |  | selectAddressType_1-default
+ADDRESS_HOME_LINE1 | address1Field | Address * |  | selectAddressType_1-default
+ADDRESS_HOME_LINE2 | address2Field | Enter the military command or organization name if applicable |  | selectAddressType_1-default
+ADDRESS_HOME_CITY | apoCity | APO/FPO * | APO | selectAddressType_1-default
+ADDRESS_HOME_STATE | apoState | Region * | AA | selectAddressType_1-default
+ADDRESS_HOME_ZIP | postalCodeField | ZIP Code * |  | selectAddressType_1-default
+UNKNOWN_TYPE | shippingMethod_single | Standard (Arrives 2-4 Days) FREE | Ground Service | selectAddressType_1-default
+UNKNOWN_TYPE | shippingMethod_single | Standard (Arrives 2-4 Days) FREE | Two Day Air | selectAddressType_1-default
+UNKNOWN_TYPE | shippingMethod_single | Standard (Arrives 2-4 Days) FREE | Next Day Air | selectAddressType_1-default
+UNKNOWN_TYPE | becomeMember | JOIN NIKE+ FOR FREE SHIPPING ON EVERY ORDER, EVERY TIME. | on | selectAddressType_1-default
+EMAIL_ADDRESS | reqEmail | Email * |  | selectAddressType_1-default
+UNKNOWN_TYPE | reqPassword | Password * |  | selectAddressType_1-default
+UNKNOWN_TYPE | monthDob | Date of Birth * |  | selectAddressType_1-default
+UNKNOWN_TYPE | dayDob | Date of Birth * |  | selectAddressType_1-default
+UNKNOWN_TYPE | yearDob | Date of Birth * |  | selectAddressType_1-default
+UNKNOWN_TYPE | gender | MALE | male | selectAddressType_1-default
+UNKNOWN_TYPE | gender | FEMALE | female | selectAddressType_1-default
+UNKNOWN_TYPE | receiveNikeOffers | I would like to be the first to hear about new products, innovations and exclusive offers. | on | selectAddressType_1-default
diff --git a/chrome/test/data/webui/md_history/history_item_test.js b/chrome/test/data/webui/md_history/history_item_test.js
index e6a2af4..e088063 100644
--- a/chrome/test/data/webui/md_history/history_item_test.js
+++ b/chrome/test/data/webui/md_history/history_item_test.js
@@ -3,26 +3,28 @@
 // found in the LICENSE file.
 
 cr.define('md_history.history_item_test', function() {
-  var TEST_HISTORY_RESULTS = [
-    {"time": "1000000000"},
-    {"time": "100000000"},
-    {"time": "9000020"},
-    {"time": "9000000"},
-    {"time": "1"}
-  ];
-
-  var SEARCH_HISTORY_RESULTS = [
-    {"dateShort": "Feb 22, 2016", "title": "Search result"},
-    {"dateShort": "Feb 21, 2016", "title": "Search result 2"},
-    {"dateShort": "Feb 21, 2016", "title": "Search result 3"},
-  ];
-
   function registerTests() {
     suite('history-item', function() {
       var element;
+      var TEST_HISTORY_RESULTS;
+      var SEARCH_HISTORY_RESULTS;
 
       suiteSetup(function() {
         element = $('history-list');
+        TEST_HISTORY_RESULTS = [
+          createHistoryEntry('2016-03-16 10:00', 'http://www.google.com'),
+          createHistoryEntry('2016-03-16 9:00', 'http://www.example.com'),
+          createHistoryEntry('2016-03-16 7:01', 'http://www.badssl.com'),
+          createHistoryEntry('2016-03-16 7:00', 'http://www.website.com'),
+          createHistoryEntry('2016-03-16 4:00', 'http://www.website.com'),
+          createHistoryEntry('2016-03-15 11:00', 'http://www.example.com'),
+        ];
+
+        SEARCH_HISTORY_RESULTS = [
+          createSearchEntry('2016-03-16', "http://www.google.com"),
+          createSearchEntry('2016-03-14', "http://calendar.google.com"),
+          createSearchEntry('2016-03-14', "http://mail.google.com")
+        ];
       });
 
       setup(function() {
@@ -40,6 +42,7 @@
           assertFalse(items[2].item.needsTimeGap);
           assertTrue(items[3].item.needsTimeGap);
           assertFalse(items[4].item.needsTimeGap);
+          assertFalse(items[5].item.needsTimeGap);
 
           done();
         });
@@ -68,7 +71,7 @@
           items[3].onCheckboxSelected_();
 
           element.removeDeletedHistory(1);
-          assertEquals(element.historyData.length, 4);
+          assertEquals(element.historyData.length, 5);
 
           // Checks that a new time gap separator has been inserted.
           assertTrue(items[2].item.needsTimeGap);
diff --git a/chrome/test/data/webui/md_history/history_list_test.js b/chrome/test/data/webui/md_history/history_list_test.js
index ede3c6d..54c9bc08 100644
--- a/chrome/test/data/webui/md_history/history_list_test.js
+++ b/chrome/test/data/webui/md_history/history_list_test.js
@@ -3,57 +3,30 @@
 // found in the LICENSE file.
 
 cr.define('md_history.history_list_test', function() {
-  // Array of test history data.
-  var TEST_HISTORY_RESULTS = [
-    {
-      "dateRelativeDay": "Today - Wednesday, December 9, 2015",
-      "title": "Google",
-      "url": "https://www.google.com"
-    },
-    {
-      "dateRelativeDay": "Yesterday - Tuesday, December 8, 2015",
-      "title": "Wikipedia",
-      "url": "https://en.wikipedia.com"
-    },
-    {
-      "dateRelativeDay": "Monday, December 7, 2015",
-      "title": "Example",
-      "url": "https://www.example.com"
-    },
-    {
-      "dateRelativeDay": "Monday, December 7, 2015",
-      "title": "Google",
-      "url": "https://www.google.com"
-    }
-  ];
-
-  var ADDITIONAL_RESULTS = [
-    {
-      "dateRelativeDay": "Monday, December 7, 2015",
-      "url": "https://en.wikipedia.com"
-    },
-    {
-      "dateRelativeDay": "Monday, December 7, 2015",
-      "url": "https://www.youtube.com"
-    },
-    {
-      "dateRelativeDay": "Sunday, December 6, 2015",
-      "url": "https://www.google.com"
-    },
-    {
-      "dateRelativeDay": "Saturday, December 5, 2015",
-      "url": "https://www.example.com"
-    }
-  ];
-
   function registerTests() {
     suite('history-list', function() {
       var element;
       var toolbar;
+      var TEST_HISTORY_RESULTS;
+      var ADDITIONAL_RESULTS;
 
       suiteSetup(function() {
         element = $('history-list');
         toolbar = $('toolbar');
+
+        TEST_HISTORY_RESULTS = [
+          createHistoryEntry('2016-03-15', 'https://www.google.com'),
+          createHistoryEntry('2016-03-14', 'https://en.wikipedia.org'),
+          createHistoryEntry('2016-03-13 10:00', 'https://www.example.com'),
+          createHistoryEntry('2016-03-13 9:00', 'https://www.google.com')
+        ];
+
+        ADDITIONAL_RESULTS = [
+          createHistoryEntry('2016-03-12 10:00', 'https://en.wikipedia.org'),
+          createHistoryEntry('2016-03-12 9:50', 'https://www.youtube.com'),
+          createHistoryEntry('2016-03-11', 'https://www.google.com'),
+          createHistoryEntry('2016-03-10', 'https://www.example.com')
+        ];
       });
 
       test('setting first and last items', function() {
@@ -124,9 +97,9 @@
           assertEquals(toBeRemoved[0].url, element.historyData[0].url);
           assertEquals(toBeRemoved[1].url, element.historyData[1].url);
           assertEquals(toBeRemoved[0].timestamps,
-                       element.historyData[0].timestamps);
+                       element.historyData[0].allTimestamps);
           assertEquals(toBeRemoved[1].timestamps,
-                       element.historyData[1].timestamps);
+                       element.historyData[1].allTimestamps);
 
           done();
         });
@@ -162,11 +135,11 @@
 
             assertEquals(element.historyData.length, 5);
             assertEquals(element.historyData[0].dateRelativeDay,
-                         "Today - Wednesday, December 9, 2015");
+                         '2016-03-15');
             assertEquals(element.historyData[2].dateRelativeDay,
-                         "Monday, December 7, 2015");
+                         '2016-03-13');
             assertEquals(element.historyData[4].dateRelativeDay,
-                         "Sunday, December 6, 2015");
+                         '2016-03-11');
 
             // Checks that the first and last items have been reset correctly.
             assertTrue(element.historyData[2].isFirstItem);
@@ -180,7 +153,9 @@
       });
 
       test('search results display with correct item title', function(done) {
-        element.addNewResults(TEST_HISTORY_RESULTS, 'Google');
+        element.addNewResults(
+            [createHistoryEntry('2016-03-15', 'https://www.google.com')],
+            'Google');
 
         flush(function() {
           assertTrue(element.historyData[0].isFirstItem);
@@ -193,7 +168,7 @@
           assertTrue(index != -1);
 
           // Check that the search term is bolded correctly in the history-item.
-          assertEquals(title.innerHTML, '<b>Google</b>');
+          assertGT(title.innerHTML.indexOf('<b>google</b>'), -1);
           done();
         });
       });
@@ -217,6 +192,7 @@
 
       teardown(function() {
         element.historyData = [];
+        registerMessageCallback('removeVisits', this, undefined);
       });
     });
   }
diff --git a/chrome/test/data/webui/md_history/history_supervised_user_test.js b/chrome/test/data/webui/md_history/history_supervised_user_test.js
index caa1abe..a39a39f 100644
--- a/chrome/test/data/webui/md_history/history_supervised_user_test.js
+++ b/chrome/test/data/webui/md_history/history_supervised_user_test.js
@@ -3,20 +3,15 @@
 // found in the LICENSE file.
 
 cr.define('md_history.history_supervised_user_test', function() {
-  // Array of test history data.
-  var TEST_HISTORY_RESULTS = [
-    {
-      "dateRelativeDay": "Today - Wednesday, December 9, 2015",
-      "url": "https://www.google.com"
-    }
-  ];
-
   function registerTests() {
     suite('history-list supervised-user', function() {
       var element;
+      var TEST_HISTORY_RESULTS;
 
       suiteSetup(function() {
         element = $('history-list');
+        TEST_HISTORY_RESULTS =
+            [createHistoryEntry('2016-03-15', 'https://www.google.com')];
       });
 
       setup(function() {
diff --git a/chrome/test/data/webui/md_history/history_toolbar_test.js b/chrome/test/data/webui/md_history/history_toolbar_test.js
index 77a9a70..b43709f6 100644
--- a/chrome/test/data/webui/md_history/history_toolbar_test.js
+++ b/chrome/test/data/webui/md_history/history_toolbar_test.js
@@ -3,23 +3,17 @@
 // found in the LICENSE file.
 
 cr.define('md_history.history_toolbar_test', function() {
-  // Array of test history data.
-  var TEST_HISTORY_RESULTS = [
-    {
-      "dateRelativeDay": "Today - Wednesday, December 9, 2015",
-      "title": "Google",
-      "url": "https://www.google.com"
-    }
-  ];
-
   function registerTests() {
     suite('history-toolbar', function() {
       var element;
       var toolbar;
+      var TEST_HISTORY_RESULTS;
 
       suiteSetup(function() {
         element = $('history-list');
         toolbar = $('toolbar');
+        TEST_HISTORY_RESULTS =
+            [createHistoryEntry('2016-03-15', 'https://google.com')];
       });
 
       test('selecting checkbox causes toolbar to change', function(done) {
@@ -59,6 +53,7 @@
 
       teardown(function() {
         element.historyData = [];
+        registerMessageCallback('queryHistory', this, undefined);
         toolbar.count = 0;
       });
     });
diff --git a/chrome/test/data/webui/md_history/test_util.js b/chrome/test/data/webui/md_history/test_util.js
index acb77f4..d0a3fc4 100644
--- a/chrome/test/data/webui/md_history/test_util.js
+++ b/chrome/test/data/webui/md_history/test_util.js
@@ -10,3 +10,48 @@
   Polymer.dom.flush();
   window.setTimeout(callback, 0);
 }
+
+/**
+ * Create a fake history result with the given timestamp.
+ * @param {number|string} timestamp Timestamp of the entry, as a number in ms or
+ * a string which can be parsed by Date.parse().
+ * @param {string} urlStr The URL to set on this entry.
+ * @return {!HistoryEntry} An object representing a history entry.
+ */
+function createHistoryEntry(timestamp, urlStr) {
+  if (typeof timestamp === 'string')
+    timestamp += ' UTC';
+
+  var d = new Date(timestamp);
+  var url = new URL(urlStr);
+  var domain = url.host;
+  return {
+    allTimestamps: [timestamp],
+    // Formatting the relative day is too hard, will instead display
+    // YYYY-MM-DD.
+    dateRelativeDay: d.toISOString().split('T')[0],
+    dateTimeOfDay: d.getUTCHours() + ':' + d.getUTCMinutes(),
+    domain: domain,
+    starred: false,
+    time: d.getTime(),
+    title: urlStr,
+    url: urlStr
+  };
+}
+
+/**
+ * Create a fake history search result with the given timestamp. Replaces fields
+ * from createHistoryEntry to look like a search result.
+ * @param {number|string} timestamp Timestamp of the entry, as a number in ms or
+ * a string which can be parsed by Date.parse().
+ * @param {string} urlStr The URL to set on this entry.
+ * @return {!HistoryEntry} An object representing a history entry.
+ */
+function createSearchEntry(timestamp, urlStr) {
+  var entry = createHistoryEntry(timestamp, urlStr);
+  entry.dateShort = entry.dateRelativeDay;
+  entry.dateTimeOfDay = '';
+  entry.dateRelativeDay = '';
+
+  return entry;
+}
diff --git a/chrome/test/data/webui/media_router/media_router_elements_browsertest.js b/chrome/test/data/webui/media_router/media_router_elements_browsertest.js
index 4ee903d..c2afb9d7 100644
--- a/chrome/test/data/webui/media_router/media_router_elements_browsertest.js
+++ b/chrome/test/data/webui/media_router/media_router_elements_browsertest.js
@@ -73,16 +73,6 @@
     // AX_ARIA_08: http://crbug.com/591552
     this.accessibilityAuditConfig.ignoreSelectors(
         'requiredOwnedAriaRoleMissing', requiredOwnedAriaRoleMissingSelectors);
-
-    // Enable when warning is resolved.
-    // AX_FOCUS_01: http://crbug.com/591553
-    this.accessibilityAuditConfig.ignoreSelectors(
-        'focusableElementNotVisibleAndNotAriaHidden', '#device-missing > A');
-
-    // Enable when warning is resolved.
-    // AX_TEXT_04: http://crbug.com/591554
-    this.accessibilityAuditConfig.ignoreSelectors(
-        'linkWithUnclearPurpose', '#device-missing > A');
   },
 };
 
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM
index fc7c224..ae28f4f1 100644
--- a/chromeos/CHROMEOS_LKGM
+++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@
-8062.0.0
\ No newline at end of file
+8069.0.0
\ No newline at end of file
diff --git a/components/autofill/core/browser/autofill_merge_unittest.cc b/components/autofill/core/browser/autofill_merge_unittest.cc
index d0c5a66f..61c58a8 100644
--- a/components/autofill/core/browser/autofill_merge_unittest.cc
+++ b/components/autofill/core/browser/autofill_merge_unittest.cc
@@ -208,6 +208,7 @@
       field.name = field_type;
       field.value = value;
       field.form_control_type = "text";
+      field.is_focusable = true;
       form.fields.push_back(field);
     }
 
@@ -225,6 +226,7 @@
             StringToFieldType(base::UTF16ToUTF8(field->name));
         field->set_heuristic_type(type);
       }
+      form_structure.IdentifySections(false);
 
       // Import the profile.
       scoped_ptr<CreditCard> imported_credit_card;
diff --git a/components/autofill/core/browser/form_structure.cc b/components/autofill/core/browser/form_structure.cc
index ed9d228..c5774de5 100644
--- a/components/autofill/core/browser/form_structure.cc
+++ b/components/autofill/core/browser/form_structure.cc
@@ -652,6 +652,7 @@
                          cached_field->second->html_mode());
       field->set_previously_autofilled(
           cached_field->second->previously_autofilled());
+      field->set_section(cached_field->second->section());
     }
   }
 
diff --git a/components/autofill/core/browser/form_structure.h b/components/autofill/core/browser/form_structure.h
index decf823..4309d1252 100644
--- a/components/autofill/core/browser/form_structure.h
+++ b/components/autofill/core/browser/form_structure.h
@@ -216,6 +216,7 @@
   bool operator!=(const FormData& form) const;
 
  private:
+  friend class AutofillMergeTest;
   friend class FormStructureTest;
   FRIEND_TEST_ALL_PREFIXES(AutofillDownloadTest, QueryAndUploadTest);
   FRIEND_TEST_ALL_PREFIXES(FormStructureTest, FindLongestCommonPrefix);
diff --git a/components/autofill/core/browser/personal_data_manager.cc b/components/autofill/core/browser/personal_data_manager.cc
index 67625af..c7ec6db 100644
--- a/components/autofill/core/browser/personal_data_manager.cc
+++ b/components/autofill/core/browser/personal_data_manager.cc
@@ -343,8 +343,9 @@
   //   |should_return_local_card|.
   bool cc_import =
       ImportCreditCard(form, should_return_local_card, imported_credit_card);
-  // - ImportAddressProfile may eventually save or update an address profile.
-  bool address_import = ImportAddressProfile(form);
+  // - ImportAddressProfiles may eventually save or update one or more address
+  //   profiles.
+  bool address_import = ImportAddressProfiles(form);
   if (cc_import || address_import)
     return true;
 
@@ -1228,7 +1229,35 @@
   NotifyPersonalDataChanged();
 }
 
-bool PersonalDataManager::ImportAddressProfile(const FormStructure& form) {
+bool PersonalDataManager::ImportAddressProfiles(const FormStructure& form) {
+  if (!form.field_count())
+    return false;
+
+  // Relevant sections for address fields.
+  std::set<std::string> sections;
+  for (const AutofillField* field : form) {
+    if (field->Type().group() != CREDIT_CARD)
+      sections.insert(field->section());
+  }
+
+  // We save a maximum of 2 profiles per submitted form (e.g. for shipping and
+  // billing).
+  static const size_t kMaxNumAddressProfilesSaved = 2;
+  size_t num_saved_profiles = 0;
+  for (const std::string& section : sections) {
+    if (num_saved_profiles == kMaxNumAddressProfilesSaved)
+      break;
+
+    if (ImportAddressProfileForSection(form, section))
+      num_saved_profiles++;
+  }
+
+  return num_saved_profiles > 0;
+}
+
+bool PersonalDataManager::ImportAddressProfileForSection(
+    const FormStructure& form,
+    const std::string& section) {
   // The candidate for profile import. There are many ways for the candidate to
   // be rejected (see everywhere this function returns false).
   AutofillProfile candidate_profile;
@@ -1244,12 +1273,17 @@
 
   // Go through each |form| field and attempt to constitute a valid profile.
   for (const AutofillField* field : form) {
+    // Reject fields that are not within the specified |section|.
+    if (field->section() != section)
+      continue;
+
     base::string16 value;
     base::TrimWhitespace(field->value, base::TRIM_ALL, &value);
 
     // If we don't know the type of the field, or the user hasn't entered any
-    // information into the field, then skip it.
-    if (!field->IsFieldFillable() || value.empty())
+    // information into the field, or the field is non-focusable (hidden), then
+    // skip it.
+    if (!field->IsFieldFillable() || !field->is_focusable || value.empty())
       continue;
 
     AutofillType field_type = field->Type();
@@ -1323,8 +1357,9 @@
     base::TrimWhitespace(field->value, base::TRIM_ALL, &value);
 
     // If we don't know the type of the field, or the user hasn't entered any
-    // information into the field, then skip it.
-    if (!field->IsFieldFillable() || value.empty())
+    // information into the field, or the field is non-focusable (hidden), then
+    // skip it.
+    if (!field->IsFieldFillable() || !field->is_focusable || value.empty())
       continue;
 
     AutofillType field_type = field->Type();
diff --git a/components/autofill/core/browser/personal_data_manager.h b/components/autofill/core/browser/personal_data_manager.h
index 8d3c52e..d8b30bc 100644
--- a/components/autofill/core/browser/personal_data_manager.h
+++ b/components/autofill/core/browser/personal_data_manager.h
@@ -361,10 +361,16 @@
   // Called when the value of prefs::kAutofillEnabled changes.
   void EnabledPrefChanged();
 
-  // Go through the |form| fields and attempt to extract and import an address
-  // profile. Returns true on extraction success. There are many reasons that
-  // extraction may fail (see implementation).
-  bool ImportAddressProfile(const FormStructure& form);
+  // Go through the |form| fields and attempt to extract and import valid
+  // address profiles. Returns true on extraction success of at least one
+  // profile. There are many reasons that extraction may fail (see
+  // implementation).
+  bool ImportAddressProfiles(const FormStructure& form);
+
+  // Helper method for ImportAddressProfiles which only considers the fields for
+  // a specified |section|.
+  bool ImportAddressProfileForSection(const FormStructure& form,
+                                      const std::string& section);
 
   // Go through the |form| fields and attempt to extract a new credit card in
   // |imported_credit_card|, or update an existing card.
diff --git a/components/autofill/core/browser/personal_data_manager_unittest.cc b/components/autofill/core/browser/personal_data_manager_unittest.cc
index 11f60fb..92f05376 100644
--- a/components/autofill/core/browser/personal_data_manager_unittest.cc
+++ b/components/autofill/core/browser/personal_data_manager_unittest.cc
@@ -262,8 +262,8 @@
   // Helper methods that simply forward the call to the private member (to avoid
   // having to friend every test that needs to access the private
   // PersonalDataManager::ImportAddressProfile or ImportCreditCard).
-  bool ImportAddressProfile(const FormStructure& form) {
-    return personal_data_->ImportAddressProfile(form);
+  bool ImportAddressProfiles(const FormStructure& form) {
+    return personal_data_->ImportAddressProfiles(form);
   }
   bool ImportCreditCard(const FormStructure& form,
                         bool should_return_local_card,
@@ -959,9 +959,9 @@
   EXPECT_EQ(profile0, *results[0]);
 }
 
-// ImportAddressProfile tests.
+// ImportAddressProfiles tests.
 
-TEST_F(PersonalDataManagerTest, ImportAddressProfile) {
+TEST_F(PersonalDataManagerTest, ImportAddressProfiles) {
   FormData form;
   FormFieldData field;
   test::CreateTestFormField(
@@ -984,7 +984,7 @@
   form.fields.push_back(field);
   FormStructure form_structure(form);
   form_structure.DetermineHeuristicTypes();
-  EXPECT_TRUE(ImportAddressProfile(form_structure));
+  EXPECT_TRUE(ImportAddressProfiles(form_structure));
 
   // Verify that the web database has been updated and the notification sent.
   EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
@@ -1000,7 +1000,7 @@
   EXPECT_EQ(0, expected.Compare(*results[0]));
 }
 
-TEST_F(PersonalDataManagerTest, ImportAddressProfile_BadEmail) {
+TEST_F(PersonalDataManagerTest, ImportAddressProfiles_BadEmail) {
   FormData form;
   FormFieldData field;
   test::CreateTestFormField(
@@ -1022,14 +1022,14 @@
   form.fields.push_back(field);
   FormStructure form_structure(form);
   form_structure.DetermineHeuristicTypes();
-  EXPECT_FALSE(ImportAddressProfile(form_structure));
+  EXPECT_FALSE(ImportAddressProfiles(form_structure));
 
   const std::vector<AutofillProfile*>& results = personal_data_->GetProfiles();
   ASSERT_EQ(0U, results.size());
 }
 
 // Tests that a 'confirm email' field does not block profile import.
-TEST_F(PersonalDataManagerTest, ImportAddressProfile_TwoEmails) {
+TEST_F(PersonalDataManagerTest, ImportAddressProfiles_TwoEmails) {
   FormData form;
   FormFieldData field;
   test::CreateTestFormField(
@@ -1052,13 +1052,13 @@
   form.fields.push_back(field);
   FormStructure form_structure(form);
   form_structure.DetermineHeuristicTypes();
-  EXPECT_TRUE(ImportAddressProfile(form_structure));
+  EXPECT_TRUE(ImportAddressProfiles(form_structure));
   const std::vector<AutofillProfile*>& results = personal_data_->GetProfiles();
   ASSERT_EQ(1U, results.size());
 }
 
 // Tests two email fields containing different values blocks profile import.
-TEST_F(PersonalDataManagerTest, ImportAddressProfile_TwoDifferentEmails) {
+TEST_F(PersonalDataManagerTest, ImportAddressProfiles_TwoDifferentEmails) {
   FormData form;
   FormFieldData field;
   test::CreateTestFormField(
@@ -1081,13 +1081,13 @@
   form.fields.push_back(field);
   FormStructure form_structure(form);
   form_structure.DetermineHeuristicTypes();
-  EXPECT_FALSE(ImportAddressProfile(form_structure));
+  EXPECT_FALSE(ImportAddressProfiles(form_structure));
   const std::vector<AutofillProfile*>& results = personal_data_->GetProfiles();
   ASSERT_EQ(0U, results.size());
 }
 
 // Tests that not enough filled fields will result in not importing an address.
-TEST_F(PersonalDataManagerTest, ImportAddressProfile_NotEnoughFilledFields) {
+TEST_F(PersonalDataManagerTest, ImportAddressProfiles_NotEnoughFilledFields) {
   FormData form;
   FormFieldData field;
   test::CreateTestFormField(
@@ -1101,7 +1101,7 @@
   form.fields.push_back(field);
   FormStructure form_structure(form);
   form_structure.DetermineHeuristicTypes();
-  EXPECT_FALSE(ImportAddressProfile(form_structure));
+  EXPECT_FALSE(ImportAddressProfiles(form_structure));
 
   const std::vector<AutofillProfile*>& profiles = personal_data_->GetProfiles();
   ASSERT_EQ(0U, profiles.size());
@@ -1109,7 +1109,7 @@
   ASSERT_EQ(0U, cards.size());
 }
 
-TEST_F(PersonalDataManagerTest, ImportAddressProfile_MinimumAddressUSA) {
+TEST_F(PersonalDataManagerTest, ImportAddressProfiles_MinimumAddressUSA) {
   // United States addresses must specifiy one address line, a city, state and
   // zip code.
   FormData form;
@@ -1129,12 +1129,12 @@
   form.fields.push_back(field);
   FormStructure form_structure(form);
   form_structure.DetermineHeuristicTypes();
-  EXPECT_TRUE(ImportAddressProfile(form_structure));
+  EXPECT_TRUE(ImportAddressProfiles(form_structure));
   const std::vector<AutofillProfile*>& profiles = personal_data_->GetProfiles();
   ASSERT_EQ(1U, profiles.size());
 }
 
-TEST_F(PersonalDataManagerTest, ImportAddressProfile_MinimumAddressGB) {
+TEST_F(PersonalDataManagerTest, ImportAddressProfiles_MinimumAddressGB) {
   // British addresses do not require a state/province as the county is usually
   // not requested on forms.
   FormData form;
@@ -1154,12 +1154,12 @@
   form.fields.push_back(field);
   FormStructure form_structure(form);
   form_structure.DetermineHeuristicTypes();
-  EXPECT_TRUE(ImportAddressProfile(form_structure));
+  EXPECT_TRUE(ImportAddressProfiles(form_structure));
   const std::vector<AutofillProfile*>& profiles = personal_data_->GetProfiles();
   ASSERT_EQ(1U, profiles.size());
 }
 
-TEST_F(PersonalDataManagerTest, ImportAddressProfile_MinimumAddressGI) {
+TEST_F(PersonalDataManagerTest, ImportAddressProfiles_MinimumAddressGI) {
   // Gibraltar has the most minimal set of requirements for a valid address.
   // There are no cities or provinces and no postal/zip code system.
   FormData form;
@@ -1174,13 +1174,13 @@
   form.fields.push_back(field);
   FormStructure form_structure(form);
   form_structure.DetermineHeuristicTypes();
-  EXPECT_TRUE(ImportAddressProfile(form_structure));
+  EXPECT_TRUE(ImportAddressProfiles(form_structure));
   const std::vector<AutofillProfile*>& profiles = personal_data_->GetProfiles();
   ASSERT_EQ(1U, profiles.size());
 }
 
 TEST_F(PersonalDataManagerTest,
-       ImportAddressProfile_PhoneNumberSplitAcrossMultipleFields) {
+       ImportAddressProfiles_PhoneNumberSplitAcrossMultipleFields) {
   FormData form;
   FormFieldData field;
   test::CreateTestFormField(
@@ -1212,7 +1212,7 @@
   form.fields.push_back(field);
   FormStructure form_structure(form);
   form_structure.DetermineHeuristicTypes();
-  EXPECT_TRUE(ImportAddressProfile(form_structure));
+  EXPECT_TRUE(ImportAddressProfiles(form_structure));
 
   // Verify that the web database has been updated and the notification sent.
   EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
@@ -1228,7 +1228,7 @@
   EXPECT_EQ(0, expected.Compare(*results[0]));
 }
 
-TEST_F(PersonalDataManagerTest, ImportAddressProfile_MultilineAddress) {
+TEST_F(PersonalDataManagerTest, ImportAddressProfiles_MultilineAddress) {
   FormData form;
   FormFieldData field;
   test::CreateTestFormField(
@@ -1256,7 +1256,7 @@
   form.fields.push_back(field);
   FormStructure form_structure(form);
   form_structure.DetermineHeuristicTypes();
-  EXPECT_TRUE(ImportAddressProfile(form_structure));
+  EXPECT_TRUE(ImportAddressProfiles(form_structure));
 
   // Verify that the web database has been updated and the notification sent.
   EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
@@ -1272,7 +1272,8 @@
   EXPECT_EQ(0, expected.Compare(*results[0]));
 }
 
-TEST_F(PersonalDataManagerTest, ImportAddressProfile_TwoValidProfiles) {
+TEST_F(PersonalDataManagerTest,
+       ImportAddressProfiles_TwoValidProfilesDifferentForms) {
   FormData form1;
   FormFieldData field;
   test::CreateTestFormField(
@@ -1296,7 +1297,7 @@
 
   FormStructure form_structure1(form1);
   form_structure1.DetermineHeuristicTypes();
-  EXPECT_TRUE(ImportAddressProfile(form_structure1));
+  EXPECT_TRUE(ImportAddressProfiles(form_structure1));
 
   // Verify that the web database has been updated and the notification sent.
   EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
@@ -1334,7 +1335,7 @@
 
   FormStructure form_structure2(form2);
   form_structure2.DetermineHeuristicTypes();
-  EXPECT_TRUE(ImportAddressProfile(form_structure2));
+  EXPECT_TRUE(ImportAddressProfiles(form_structure2));
 
   // Verify that the web database has been updated and the notification sent.
   EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
@@ -1351,7 +1352,239 @@
   ExpectSameElements(profiles, personal_data_->GetProfiles());
 }
 
-TEST_F(PersonalDataManagerTest, ImportAddressProfile_SameProfileWithConflict) {
+TEST_F(PersonalDataManagerTest,
+       ImportAddressProfiles_TwoValidProfilesSameForm) {
+  FormData form;
+  FormFieldData field;
+  test::CreateTestFormField("First name:", "first_name", "George", "text",
+                            &field);
+  form.fields.push_back(field);
+  test::CreateTestFormField("Last name:", "last_name", "Washington", "text",
+                            &field);
+  form.fields.push_back(field);
+  test::CreateTestFormField("Email:", "email", "theprez@gmail.com", "text",
+                            &field);
+  form.fields.push_back(field);
+  test::CreateTestFormField("Address:", "address1", "21 Laussat St", "text",
+                            &field);
+  form.fields.push_back(field);
+  test::CreateTestFormField("City:", "city", "San Francisco", "text", &field);
+  form.fields.push_back(field);
+  test::CreateTestFormField("State:", "state", "California", "text", &field);
+  form.fields.push_back(field);
+  test::CreateTestFormField("Zip:", "zip", "94102", "text", &field);
+  form.fields.push_back(field);
+
+  // Different address.
+  test::CreateTestFormField("First name:", "first_name", "John", "text",
+                            &field);
+  form.fields.push_back(field);
+  test::CreateTestFormField("Last name:", "last_name", "Adams", "text", &field);
+  form.fields.push_back(field);
+  test::CreateTestFormField("Email:", "email", "second@gmail.com", "text",
+                            &field);
+  form.fields.push_back(field);
+  test::CreateTestFormField("Address:", "address1", "22 Laussat St", "text",
+                            &field);
+  form.fields.push_back(field);
+  test::CreateTestFormField("City:", "city", "San Francisco", "text", &field);
+  form.fields.push_back(field);
+  test::CreateTestFormField("State:", "state", "California", "text", &field);
+  form.fields.push_back(field);
+  test::CreateTestFormField("Zip:", "zip", "94102", "text", &field);
+  form.fields.push_back(field);
+
+  FormStructure form_structure(form);
+  form_structure.DetermineHeuristicTypes();
+  EXPECT_TRUE(ImportAddressProfiles(form_structure));
+
+  // Verify that the web database has been updated and the notification sent.
+  EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
+      .WillOnce(QuitMainMessageLoop());
+  base::MessageLoop::current()->Run();
+
+  AutofillProfile expected(base::GenerateGUID(), "https://www.example.com");
+  test::SetProfileInfo(&expected, "George", NULL, "Washington",
+                       "theprez@gmail.com", NULL, "21 Laussat St", NULL,
+                       "San Francisco", "California", "94102", NULL, NULL);
+  AutofillProfile expected2(base::GenerateGUID(), "https://www.example.com");
+  test::SetProfileInfo(&expected2, "John", NULL, "Adams", "second@gmail.com",
+                       NULL, "22 Laussat St", NULL, "San Francisco",
+                       "California", "94102", NULL, NULL);
+
+  const std::vector<AutofillProfile*>& results = personal_data_->GetProfiles();
+  ASSERT_EQ(2U, results.size());
+
+  std::vector<AutofillProfile*> profiles;
+  profiles.push_back(&expected);
+  profiles.push_back(&expected2);
+  ExpectSameElements(profiles, personal_data_->GetProfiles());
+}
+
+TEST_F(PersonalDataManagerTest,
+       ImportAddressProfiles_OneValidProfileSameForm_PartsHidden) {
+  FormData form;
+  FormFieldData field;
+  test::CreateTestFormField("First name:", "first_name", "George", "text",
+                            &field);
+  form.fields.push_back(field);
+  test::CreateTestFormField("Last name:", "last_name", "Washington", "text",
+                            &field);
+  form.fields.push_back(field);
+  test::CreateTestFormField("Email:", "email", "theprez@gmail.com", "text",
+                            &field);
+  form.fields.push_back(field);
+  test::CreateTestFormField("Address:", "address1", "21 Laussat St", "text",
+                            &field);
+  form.fields.push_back(field);
+  test::CreateTestFormField("City:", "city", "San Francisco", "text", &field);
+  form.fields.push_back(field);
+  test::CreateTestFormField("State:", "state", "California", "text", &field);
+  form.fields.push_back(field);
+  test::CreateTestFormField("Zip:", "zip", "94102", "text", &field);
+  form.fields.push_back(field);
+
+  // There is an empty but hidden form section (this has been observed on sites
+  // where users can choose which form section they choose by unhiding it).
+  test::CreateTestFormField("First name:", "first_name", "", "text",
+                            &field);
+  field.is_focusable = false;
+  form.fields.push_back(field);
+  test::CreateTestFormField("Last name:", "last_name", "", "text", &field);
+  field.is_focusable = false;
+  form.fields.push_back(field);
+  test::CreateTestFormField("Email:", "email", "", "text",
+                            &field);
+  field.is_focusable = false;
+  form.fields.push_back(field);
+  test::CreateTestFormField("Address:", "address1", "", "text",
+                            &field);
+  field.is_focusable = false;
+  form.fields.push_back(field);
+  test::CreateTestFormField("City:", "city", "", "text", &field);
+  field.is_focusable = false;
+  form.fields.push_back(field);
+  test::CreateTestFormField("State:", "state", "", "text", &field);
+  field.is_focusable = false;
+  form.fields.push_back(field);
+  test::CreateTestFormField("Zip:", "zip", "", "text", &field);
+  field.is_focusable = false;
+  form.fields.push_back(field);
+
+  // Still able to do the import.
+  FormStructure form_structure(form);
+  form_structure.DetermineHeuristicTypes();
+  EXPECT_TRUE(ImportAddressProfiles(form_structure));
+
+  // Verify that the web database has been updated and the notification sent.
+  EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
+      .WillOnce(QuitMainMessageLoop());
+  base::MessageLoop::current()->Run();
+
+  AutofillProfile expected(base::GenerateGUID(), "https://www.example.com");
+  test::SetProfileInfo(&expected, "George", NULL, "Washington",
+                       "theprez@gmail.com", NULL, "21 Laussat St", NULL,
+                       "San Francisco", "California", "94102", NULL, NULL);
+
+  const std::vector<AutofillProfile*>& results = personal_data_->GetProfiles();
+  ASSERT_EQ(1U, results.size());
+
+  std::vector<AutofillProfile*> profiles;
+  profiles.push_back(&expected);
+  ExpectSameElements(profiles, personal_data_->GetProfiles());
+}
+
+// A maximum of two address profiles are imported per form.
+TEST_F(PersonalDataManagerTest,
+       ImportAddressProfiles_ThreeValidProfilesSameForm) {
+  FormData form;
+  FormFieldData field;
+  test::CreateTestFormField("First name:", "first_name", "George", "text",
+                            &field);
+  form.fields.push_back(field);
+  test::CreateTestFormField("Last name:", "last_name", "Washington", "text",
+                            &field);
+  form.fields.push_back(field);
+  test::CreateTestFormField("Email:", "email", "theprez@gmail.com", "text",
+                            &field);
+  form.fields.push_back(field);
+  test::CreateTestFormField("Address:", "address1", "21 Laussat St", "text",
+                            &field);
+  form.fields.push_back(field);
+  test::CreateTestFormField("City:", "city", "San Francisco", "text", &field);
+  form.fields.push_back(field);
+  test::CreateTestFormField("State:", "state", "California", "text", &field);
+  form.fields.push_back(field);
+  test::CreateTestFormField("Zip:", "zip", "94102", "text", &field);
+  form.fields.push_back(field);
+
+  // Different address within the same form.
+  test::CreateTestFormField("First name:", "first_name", "John", "text",
+                            &field);
+  form.fields.push_back(field);
+  test::CreateTestFormField("Last name:", "last_name", "Adams", "text", &field);
+  form.fields.push_back(field);
+  test::CreateTestFormField("Email:", "email", "second@gmail.com", "text",
+                            &field);
+  form.fields.push_back(field);
+  test::CreateTestFormField("Address:", "address1", "22 Laussat St", "text",
+                            &field);
+  form.fields.push_back(field);
+  test::CreateTestFormField("City:", "city", "San Francisco", "text", &field);
+  form.fields.push_back(field);
+  test::CreateTestFormField("State:", "state", "California", "text", &field);
+  form.fields.push_back(field);
+  test::CreateTestFormField("Zip:", "zip", "94102", "text", &field);
+  form.fields.push_back(field);
+
+  // Yet another different address.
+  test::CreateTestFormField("First name:", "first_name", "David", "text",
+                            &field);
+  form.fields.push_back(field);
+  test::CreateTestFormField("Last name:", "last_name", "Cameron", "text",
+                            &field);
+  form.fields.push_back(field);
+  test::CreateTestFormField("Address:", "address", "10 Downing Street", "text",
+                            &field);
+  form.fields.push_back(field);
+  test::CreateTestFormField("City:", "city", "London", "text", &field);
+  form.fields.push_back(field);
+  test::CreateTestFormField("Postcode:", "postcode", "SW1A 2AA", "text",
+                            &field);
+  form.fields.push_back(field);
+  test::CreateTestFormField("Country:", "country", "United Kingdom", "text",
+                            &field);
+  form.fields.push_back(field);
+
+  FormStructure form_structure(form);
+  form_structure.DetermineHeuristicTypes();
+  EXPECT_TRUE(ImportAddressProfiles(form_structure));
+
+  // Verify that the web database has been updated and the notification sent.
+  EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
+      .WillOnce(QuitMainMessageLoop());
+  base::MessageLoop::current()->Run();
+
+  // Only two are saved.
+  AutofillProfile expected(base::GenerateGUID(), "https://www.example.com");
+  test::SetProfileInfo(&expected, "George", NULL, "Washington",
+                       "theprez@gmail.com", NULL, "21 Laussat St", NULL,
+                       "San Francisco", "California", "94102", NULL, NULL);
+  AutofillProfile expected2(base::GenerateGUID(), "https://www.example.com");
+  test::SetProfileInfo(&expected2, "John", NULL, "Adams", "second@gmail.com",
+                       NULL, "22 Laussat St", NULL, "San Francisco",
+                       "California", "94102", NULL, NULL);
+
+  const std::vector<AutofillProfile*>& results = personal_data_->GetProfiles();
+  ASSERT_EQ(2U, results.size());
+
+  std::vector<AutofillProfile*> profiles;
+  profiles.push_back(&expected);
+  profiles.push_back(&expected2);
+  ExpectSameElements(profiles, personal_data_->GetProfiles());
+}
+
+TEST_F(PersonalDataManagerTest, ImportAddressProfiles_SameProfileWithConflict) {
   FormData form1;
   FormFieldData field;
   test::CreateTestFormField(
@@ -1380,7 +1613,7 @@
 
   FormStructure form_structure1(form1);
   form_structure1.DetermineHeuristicTypes();
-  EXPECT_TRUE(ImportAddressProfile(form_structure1));
+  EXPECT_TRUE(ImportAddressProfiles(form_structure1));
 
   // Verify that the web database has been updated and the notification sent.
   EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
@@ -1428,7 +1661,7 @@
 
   FormStructure form_structure2(form2);
   form_structure2.DetermineHeuristicTypes();
-  EXPECT_TRUE(ImportAddressProfile(form_structure2));
+  EXPECT_TRUE(ImportAddressProfiles(form_structure2));
 
   // Verify that the web database has been updated and the notification sent.
   EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
@@ -1444,7 +1677,7 @@
   EXPECT_EQ(0, expected.Compare(*results2[0]));
 }
 
-TEST_F(PersonalDataManagerTest, ImportAddressProfile_MissingInfoInOld) {
+TEST_F(PersonalDataManagerTest, ImportAddressProfiles_MissingInfoInOld) {
   FormData form1;
   FormFieldData field;
   test::CreateTestFormField(
@@ -1465,7 +1698,7 @@
 
   FormStructure form_structure1(form1);
   form_structure1.DetermineHeuristicTypes();
-  EXPECT_TRUE(ImportAddressProfile(form_structure1));
+  EXPECT_TRUE(ImportAddressProfiles(form_structure1));
 
   // Verify that the web database has been updated and the notification sent.
   EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
@@ -1503,7 +1736,7 @@
 
   FormStructure form_structure2(form2);
   form_structure2.DetermineHeuristicTypes();
-  EXPECT_TRUE(ImportAddressProfile(form_structure2));
+  EXPECT_TRUE(ImportAddressProfiles(form_structure2));
 
   // Verify that the web database has been updated and the notification sent.
   EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
@@ -1520,7 +1753,7 @@
   EXPECT_EQ(0, expected2.Compare(*results2[0]));
 }
 
-TEST_F(PersonalDataManagerTest, ImportAddressProfile_MissingInfoInNew) {
+TEST_F(PersonalDataManagerTest, ImportAddressProfiles_MissingInfoInNew) {
   FormData form1;
   FormFieldData field;
   test::CreateTestFormField(
@@ -1547,7 +1780,7 @@
 
   FormStructure form_structure1(form1);
   form_structure1.DetermineHeuristicTypes();
-  EXPECT_TRUE(ImportAddressProfile(form_structure1));
+  EXPECT_TRUE(ImportAddressProfiles(form_structure1));
 
   // Verify that the web database has been updated and the notification sent.
   EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
@@ -1586,7 +1819,7 @@
 
   FormStructure form_structure2(form2);
   form_structure2.DetermineHeuristicTypes();
-  EXPECT_TRUE(ImportAddressProfile(form_structure2));
+  EXPECT_TRUE(ImportAddressProfiles(form_structure2));
 
   // Verify that the web database has been updated and the notification sent.
   EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
@@ -1600,7 +1833,7 @@
   EXPECT_EQ(0, expected.Compare(*results2[0]));
 }
 
-TEST_F(PersonalDataManagerTest, ImportAddressProfile_InsufficientAddress) {
+TEST_F(PersonalDataManagerTest, ImportAddressProfiles_InsufficientAddress) {
   FormData form1;
   FormFieldData field;
   test::CreateTestFormField(
@@ -1623,7 +1856,7 @@
 
   FormStructure form_structure1(form1);
   form_structure1.DetermineHeuristicTypes();
-  EXPECT_FALSE(ImportAddressProfile(form_structure1));
+  EXPECT_FALSE(ImportAddressProfiles(form_structure1));
 
   // Since no refresh is expected, reload the data from the database to make
   // sure no changes were written out.
@@ -1640,7 +1873,7 @@
 // works: if either the full name OR all the non-empty name pieces match, the
 // profile is a match.
 TEST_F(PersonalDataManagerTest,
-       ImportAddressProfile_ExistingVerifiedProfileWithConflict) {
+       ImportAddressProfiles_ExistingVerifiedProfileWithConflict) {
   // Start with a verified profile.
   AutofillProfile profile(base::GenerateGUID(), "Chrome settings");
   test::SetProfileInfo(&profile, "Marion", "Mitchell", "Morrison",
@@ -1680,7 +1913,7 @@
 
   FormStructure form_structure(form);
   form_structure.DetermineHeuristicTypes();
-  EXPECT_TRUE(ImportAddressProfile(form_structure));
+  EXPECT_TRUE(ImportAddressProfiles(form_structure));
 
   // Wait for the refresh, which in this case is a no-op.
   EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
@@ -1701,7 +1934,7 @@
 
   FormStructure form_structure2(form);
   form_structure2.DetermineHeuristicTypes();
-  EXPECT_TRUE(ImportAddressProfile(form_structure2));
+  EXPECT_TRUE(ImportAddressProfiles(form_structure2));
 
   // Wait for the refresh, which in this case is a no-op.
   EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
@@ -2387,8 +2620,8 @@
       .WillOnce(QuitMainMessageLoop());
   base::MessageLoop::current()->Run();
 
-  // Test that the address has NOT been saved.
-  EXPECT_TRUE(personal_data_->GetProfiles().empty());
+  // Test that both addresses have been saved.
+  EXPECT_EQ(2U, personal_data_->GetProfiles().size());
 
   // Test that the credit card has been saved.
   CreditCard expected_card(base::GenerateGUID(), "https://www.example.com");
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h b/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h
index 44f45280..093c6ab 100644
--- a/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h
@@ -78,10 +78,6 @@
 // requests and responses.
 const char* chrome_proxy_lo_fi_preview_directive();
 
-// Gets the Chrome-Proxy directive used by data reduction proxy Lo-Fi control
-// experiment requests.
-const char* chrome_proxy_lo_fi_experiment_directive();
-
 // Returns true if the Chrome-Proxy header is present and contains a bypass
 // delay. Sets |proxy_info->bypass_duration| to the specified delay if greater
 // than 0, and to 0 otherwise to indicate that the default proxy delay
diff --git a/components/metrics/file_metrics_provider.cc b/components/metrics/file_metrics_provider.cc
index 7fad01c..fcfb7acf 100644
--- a/components/metrics/file_metrics_provider.cc
+++ b/components/metrics/file_metrics_provider.cc
@@ -11,7 +11,7 @@
 #include "base/logging.h"
 #include "base/metrics/histogram_base.h"
 #include "base/metrics/histogram_macros.h"
-#include "base/metrics/histogram_persistence.h"
+#include "base/metrics/persistent_histogram_allocator.h"
 #include "base/metrics/persistent_memory_allocator.h"
 #include "base/task_runner.h"
 #include "base/time/time.h"
@@ -47,7 +47,7 @@
   // "active", it remains mapped and nothing is copied to local memory.
   std::vector<uint8_t> data;
   scoped_ptr<base::MemoryMappedFile> mapped;
-  scoped_ptr<base::PersistentMemoryAllocator> allocator;
+  scoped_ptr<base::PersistentHistogramAllocator> allocator;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(FileInfo);
@@ -174,13 +174,13 @@
     base::HistogramSnapshotManager* snapshot_manager,
     FileInfo* file) {
   DCHECK(thread_checker_.CalledOnValidThread());
-  base::PersistentMemoryAllocator::Iterator hist_iter;
-  file->allocator->CreateIterator(&hist_iter);
+  base::PersistentHistogramAllocator::Iterator histogram_iter;
+  file->allocator->CreateIterator(&histogram_iter);
 
   int histogram_count = 0;
   while (true) {
-    scoped_ptr<base::HistogramBase> histogram(
-        base::GetNextPersistentHistogram(file->allocator.get(), &hist_iter));
+    scoped_ptr<base::HistogramBase> histogram =
+        file->allocator->GetNextHistogram(&histogram_iter);
     if (!histogram)
       break;
     if (file->type == FILE_HISTOGRAMS_ATOMIC)
@@ -204,12 +204,14 @@
   if (file->mapped) {
     DCHECK(file->data.empty());
     // TODO(bcwhite): Make this do read/write when supported for "active".
-    file->allocator.reset(new base::FilePersistentMemoryAllocator(
-        std::move(file->mapped), 0, std::string()));
+    file->allocator.reset(new base::PersistentHistogramAllocator(
+        make_scoped_ptr(new base::FilePersistentMemoryAllocator(
+            std::move(file->mapped), 0, ""))));
   } else {
     DCHECK(!file->mapped);
-    file->allocator.reset(new base::PersistentMemoryAllocator(
-        &file->data[0], file->data.size(), 0, 0, "", true));
+    file->allocator.reset(new base::PersistentHistogramAllocator(
+        make_scoped_ptr(new base::PersistentMemoryAllocator(
+            &file->data[0], file->data.size(), 0, 0, "", true))));
   }
 }
 
diff --git a/components/metrics/file_metrics_provider_unittest.cc b/components/metrics/file_metrics_provider_unittest.cc
index 3bffb1c..425777f 100644
--- a/components/metrics/file_metrics_provider_unittest.cc
+++ b/components/metrics/file_metrics_provider_unittest.cc
@@ -9,8 +9,8 @@
 #include "base/files/scoped_temp_dir.h"
 #include "base/metrics/histogram.h"
 #include "base/metrics/histogram_flattener.h"
-#include "base/metrics/histogram_persistence.h"
 #include "base/metrics/histogram_snapshot_manager.h"
+#include "base/metrics/persistent_histogram_allocator.h"
 #include "base/metrics/persistent_memory_allocator.h"
 #include "base/metrics/statistics_recorder.h"
 #include "base/test/test_simple_task_runner.h"
@@ -103,10 +103,10 @@
 
   {
     // Get this first so it isn't created inside the persistent allocator.
-    base::GetCreateHistogramResultHistogram();
+    base::PersistentHistogramAllocator::GetCreateHistogramResultHistogram();
 
-    base::SetPersistentHistogramMemoryAllocator(
-        new base::LocalPersistentMemoryAllocator(64 << 10, 0, kMetricsName));
+    base::PersistentHistogramAllocator::CreateGlobalAllocatorOnLocalMemory(
+        64 << 10, 0, kMetricsName);
     base::HistogramBase* foo =
         base::Histogram::FactoryGet("foo", 1, 100, 10, 0);
     base::HistogramBase* bar =
@@ -114,8 +114,10 @@
     foo->Add(42);
     bar->Add(84);
 
-    scoped_ptr<base::PersistentMemoryAllocator> allocator(
-        base::ReleasePersistentHistogramMemoryAllocatorForTesting());
+    scoped_ptr<base::PersistentHistogramAllocator> histogram_allocator =
+        base::PersistentHistogramAllocator::ReleaseGlobalAllocatorForTesting();
+    base::PersistentMemoryAllocator* allocator =
+        histogram_allocator->memory_allocator();
     base::File writer(metrics_file(),
                       base::File::FLAG_CREATE | base::File::FLAG_WRITE);
     ASSERT_TRUE(writer.IsValid());
diff --git a/components/metrics/metrics_service.cc b/components/metrics/metrics_service.cc
index d17911a0..c3ef7ec 100644
--- a/components/metrics/metrics_service.cc
+++ b/components/metrics/metrics_service.cc
@@ -133,8 +133,8 @@
 #include "base/location.h"
 #include "base/metrics/histogram_base.h"
 #include "base/metrics/histogram_macros.h"
-#include "base/metrics/histogram_persistence.h"
 #include "base/metrics/histogram_samples.h"
+#include "base/metrics/persistent_histogram_allocator.h"
 #include "base/metrics/sparse_histogram.h"
 #include "base/metrics/statistics_recorder.h"
 #include "base/rand_util.h"
@@ -746,8 +746,8 @@
 
   // If a persistent allocator is in use, update its internal histograms (such
   // as how much memory is being used) before reporting.
-  base::PersistentMemoryAllocator* allocator =
-      base::GetPersistentHistogramMemoryAllocator();
+  base::PersistentHistogramAllocator* allocator =
+      base::PersistentHistogramAllocator::GetGlobalAllocator();
   if (allocator)
     allocator->UpdateTrackingHistograms();
 
diff --git a/content/browser/background_sync/background_sync_manager.cc b/content/browser/background_sync/background_sync_manager.cc
index 79f2c78..9fe2d47 100644
--- a/content/browser/background_sync/background_sync_manager.cc
+++ b/content/browser/background_sync/background_sync_manager.cc
@@ -710,6 +710,7 @@
 
   if (active_version->running_status() != ServiceWorkerVersion::RUNNING) {
     active_version->RunAfterStartWorker(
+        ServiceWorkerMetrics::EventType::SYNC,
         base::Bind(&BackgroundSyncManager::DispatchSyncEvent,
                    weak_ptr_factory_.GetWeakPtr(), tag, active_version,
                    last_chance, callback),
diff --git a/content/browser/compositor/browser_compositor_overlay_candidate_validator_mac.mm b/content/browser/compositor/browser_compositor_overlay_candidate_validator_mac.mm
index a7e99a2b..3e9886b 100644
--- a/content/browser/compositor/browser_compositor_overlay_candidate_validator_mac.mm
+++ b/content/browser/compositor/browser_compositor_overlay_candidate_validator_mac.mm
@@ -6,8 +6,10 @@
 
 #include <stddef.h>
 
+#include "base/command_line.h"
 #include "content/browser/gpu/gpu_data_manager_impl.h"
 #include "gpu/config/gpu_driver_bug_workaround_type.h"
+#include "ui/base/ui_base_switches.h"
 
 namespace content {
 
@@ -30,7 +32,11 @@
 }
 
 bool BrowserCompositorOverlayCandidateValidatorMac::AllowCALayerOverlays() {
-  if (software_mirror_active_ || ca_layers_disabled_)
+  static bool overlays_disabled_at_command_line =
+      base::CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kDisableMacOverlays);
+  if (software_mirror_active_ || ca_layers_disabled_ ||
+      overlays_disabled_at_command_line)
     return false;
   return true;
 }
diff --git a/content/browser/geofencing/geofencing_manager.cc b/content/browser/geofencing/geofencing_manager.cc
index 242b588..e420d5f 100644
--- a/content/browser/geofencing/geofencing_manager.cc
+++ b/content/browser/geofencing/geofencing_manager.cc
@@ -395,6 +395,7 @@
   // until the callback dies. Otherwise the registration could be released when
   // this method returns - before the event is delivered to the service worker.
   active_version->RunAfterStartWorker(
+      ServiceWorkerMetrics::EventType::GEOFENCING,
       base::Bind(&GeofencingManager::DeliverEventToRunningWorker, this,
                  service_worker_registration, event_type,
                  registration->region_id, registration->region,
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc
index dbc3da5..0472eb6 100644
--- a/content/browser/gpu/gpu_process_host.cc
+++ b/content/browser/gpu/gpu_process_host.cc
@@ -132,7 +132,6 @@
   switches::kVModule,
 #if defined(OS_MACOSX)
   switches::kDisableRemoteCoreAnimation,
-  switches::kDisableMacOverlays,
   switches::kEnableSandboxLogging,
   switches::kShowMacOverlayBorders,
 #endif
diff --git a/content/browser/navigator_connect/navigator_connect_context_impl.cc b/content/browser/navigator_connect/navigator_connect_context_impl.cc
index 5aaeba1..e943aba7 100644
--- a/content/browser/navigator_connect/navigator_connect_context_impl.cc
+++ b/content/browser/navigator_connect/navigator_connect_context_impl.cc
@@ -5,6 +5,7 @@
 #include "content/browser/navigator_connect/navigator_connect_context_impl.h"
 
 #include <stdint.h>
+#include <vector>
 
 #include "base/stl_util.h"
 #include "content/browser/message_port_service.h"
@@ -154,6 +155,7 @@
       registration->pattern().GetOrigin();
 
   active_version->RunAfterStartWorker(
+      ServiceWorkerMetrics::EventType::SERVICE_PORT_CONNECT,
       base::Bind(&NavigatorConnectContextImpl::DispatchConnectEvent, this,
                  callback, client_port_id, service_port_id, registration,
                  make_scoped_refptr(active_version)),
diff --git a/content/browser/notifications/notification_event_dispatcher_impl.cc b/content/browser/notifications/notification_event_dispatcher_impl.cc
index ca125fa5..e19a1f81 100644
--- a/content/browser/notifications/notification_event_dispatcher_impl.cc
+++ b/content/browser/notifications/notification_event_dispatcher_impl.cc
@@ -228,6 +228,7 @@
   ServiceWorkerVersion::StatusCallback status_callback = base::Bind(
       &ServiceWorkerNotificationEventFinished, dispatch_complete_callback);
   service_worker_registration->active_version()->RunAfterStartWorker(
+      ServiceWorkerMetrics::EventType::NOTIFICATION_CLICK,
       base::Bind(
           &DispatchNotificationClickEventOnWorker,
           make_scoped_refptr(service_worker_registration->active_version()),
@@ -299,6 +300,7 @@
                  dispatch_complete_callback);
   if (by_user) {
     service_worker_registration->active_version()->RunAfterStartWorker(
+        ServiceWorkerMetrics::EventType::NOTIFICATION_CLOSE,
         base::Bind(
             &DispatchNotificationCloseEventOnWorker,
             make_scoped_refptr(service_worker_registration->active_version()),
diff --git a/content/browser/push_messaging/push_messaging_router.cc b/content/browser/push_messaging/push_messaging_router.cc
index 7bc469b..dce24a9 100644
--- a/content/browser/push_messaging/push_messaging_router.cc
+++ b/content/browser/push_messaging/push_messaging_router.cc
@@ -91,6 +91,7 @@
   // released when this method returns - before the event is delivered to the
   // service worker.
   version->RunAfterStartWorker(
+      ServiceWorkerMetrics::EventType::PUSH,
       base::Bind(&PushMessagingRouter::DeliverMessageToWorker,
                  make_scoped_refptr(version), service_worker_registration,
                  payload, deliver_message_callback),
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc
index 65ed654..3f15cf30 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.cc
+++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -128,7 +128,11 @@
   void onContextLost() override;
 
   GLHelper* GetGLHelper() { return gl_helper_.get(); }
-  bool IsLost() { return !context_.get() || context_->isContextLost(); }
+  bool IsLost() {
+    return !context_ ||
+           context_->GetGLInterface()->GetGraphicsResetStatusKHR() !=
+               GL_NO_ERROR;
+  }
 
  private:
   GLHelperHolder();
diff --git a/content/browser/service_worker/foreign_fetch_request_handler.cc b/content/browser/service_worker/foreign_fetch_request_handler.cc
index b4cce4a..be692ce 100644
--- a/content/browser/service_worker/foreign_fetch_request_handler.cc
+++ b/content/browser/service_worker/foreign_fetch_request_handler.cc
@@ -4,6 +4,8 @@
 
 #include "content/browser/service_worker/foreign_fetch_request_handler.h"
 
+#include <string>
+
 #include "base/macros.h"
 #include "content/browser/service_worker/service_worker_context_wrapper.h"
 #include "content/browser/service_worker/service_worker_url_request_job.h"
@@ -120,8 +122,8 @@
 
   ServiceWorkerURLRequestJob* job = new ServiceWorkerURLRequestJob(
       request, network_delegate, std::string(), blob_storage_context_,
-      resource_context, request_mode_, credentials_mode_, redirect_mode_, false,
-      request_context_type_, frame_type_, body_,
+      resource_context, request_mode_, credentials_mode_, redirect_mode_,
+      resource_type_, request_context_type_, frame_type_, body_,
       ServiceWorkerFetchType::FOREIGN_FETCH, this);
   job_ = job->GetWeakPtr();
 
diff --git a/content/browser/service_worker/service_worker_browsertest.cc b/content/browser/service_worker/service_worker_browsertest.cc
index dda9572..58862d6b 100644
--- a/content/browser/service_worker/service_worker_browsertest.cc
+++ b/content/browser/service_worker/service_worker_browsertest.cc
@@ -41,6 +41,7 @@
 #include "content/public/common/content_client.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/common/referrer.h"
+#include "content/public/common/resource_type.h"
 #include "content/public/common/security_style.h"
 #include "content/public/common/ssl_status.h"
 #include "content/public/common/web_preferences.h"
@@ -226,7 +227,7 @@
 // an experiration far in the future.
 class LongLivedResourceInterceptor : public net::URLRequestInterceptor {
  public:
-  LongLivedResourceInterceptor(const std::string& body)
+  explicit LongLivedResourceInterceptor(const std::string& body)
       : body_(body) {}
   ~LongLivedResourceInterceptor() override {}
 
@@ -592,7 +593,8 @@
   void StartOnIOThread(const base::Closure& done,
                        ServiceWorkerStatusCode* result) {
     ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
-    version_->StartWorker(CreateReceiver(BrowserThread::UI, done, result));
+    version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
+                          CreateReceiver(BrowserThread::UI, done, result));
   }
 
   void InstallOnIOThread(const base::Closure& done,
@@ -600,6 +602,7 @@
     ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
     version_->SetStatus(ServiceWorkerVersion::INSTALLING);
     version_->RunAfterStartWorker(
+        ServiceWorkerMetrics::EventType::INSTALL,
         base::Bind(&self::DispatchInstallEventOnIOThread, this, done, result),
         CreateReceiver(BrowserThread::UI, done, result));
   }
@@ -631,6 +634,7 @@
     version_->SetStatus(ServiceWorkerVersion::ACTIVATING);
     registration_->SetActiveVersion(version_.get());
     version_->RunAfterStartWorker(
+        ServiceWorkerMetrics::EventType::ACTIVATE,
         base::Bind(&self::DispatchActivateEventOnIOThread, this, done, result),
         CreateReceiver(BrowserThread::UI, done, result));
   }
@@ -654,7 +658,7 @@
         ServiceWorkerHeaderMap(), Referrer(), false));
     version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
     fetch_dispatcher_.reset(new ServiceWorkerFetchDispatcher(
-        std::move(request), version_.get(),
+        std::move(request), version_.get(), RESOURCE_TYPE_MAIN_FRAME,
         CreatePrepareReceiver(prepare_result),
         CreateResponseReceiver(done, blob_context_.get(), result)));
     fetch_dispatcher_->Run();
@@ -877,7 +881,7 @@
 
 class WaitForLoaded : public EmbeddedWorkerInstance::Listener {
  public:
-  WaitForLoaded(const base::Closure& quit) : quit_(quit) {}
+  explicit WaitForLoaded(const base::Closure& quit) : quit_(quit) {}
 
   void OnThreadStarted() override {
     BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, quit_);
diff --git a/content/browser/service_worker/service_worker_context_wrapper.cc b/content/browser/service_worker/service_worker_context_wrapper.cc
index 770a78a..cba52e97 100644
--- a/content/browser/service_worker/service_worker_context_wrapper.cc
+++ b/content/browser/service_worker/service_worker_context_wrapper.cc
@@ -62,6 +62,7 @@
     // it from being deleted while starting the worker. If the refcount of
     // |registration| is 1, it will be deleted after WorkerStarted is called.
     registration->active_version()->StartWorker(
+        ServiceWorkerMetrics::EventType::UNKNOWN,
         base::Bind(WorkerStarted, callback));
     return;
   }
diff --git a/content/browser/service_worker/service_worker_controllee_request_handler.cc b/content/browser/service_worker/service_worker_controllee_request_handler.cc
index 4dd83758..c6089fc5 100644
--- a/content/browser/service_worker/service_worker_controllee_request_handler.cc
+++ b/content/browser/service_worker/service_worker_controllee_request_handler.cc
@@ -103,8 +103,8 @@
   scoped_ptr<ServiceWorkerURLRequestJob> job(new ServiceWorkerURLRequestJob(
       request, network_delegate, provider_host_->client_uuid(),
       blob_storage_context_, resource_context, request_mode_, credentials_mode_,
-      redirect_mode_, is_main_resource_load_, request_context_type_,
-      frame_type_, body_, ServiceWorkerFetchType::FETCH, this));
+      redirect_mode_, resource_type_, request_context_type_, frame_type_, body_,
+      ServiceWorkerFetchType::FETCH, this));
   job_ = job->GetWeakPtr();
 
   resource_context_ = resource_context;
diff --git a/content/browser/service_worker/service_worker_dispatcher_host.cc b/content/browser/service_worker/service_worker_dispatcher_host.cc
index 4dd4cb34..d75ab4a 100644
--- a/content/browser/service_worker/service_worker_dispatcher_host.cc
+++ b/content/browser/service_worker/service_worker_dispatcher_host.cc
@@ -878,6 +878,7 @@
     return;
   }
   worker->RunAfterStartWorker(
+      ServiceWorkerMetrics::EventType::MESSAGE,
       base::Bind(&ServiceWorkerDispatcherHost::
                      DispatchExtendableMessageEventAfterStartWorker,
                  this, worker, message, source_origin, sent_message_ports,
diff --git a/content/browser/service_worker/service_worker_dispatcher_host_unittest.cc b/content/browser/service_worker/service_worker_dispatcher_host_unittest.cc
index 84e1b6e..9bce9ae 100644
--- a/content/browser/service_worker/service_worker_dispatcher_host_unittest.cc
+++ b/content/browser/service_worker/service_worker_dispatcher_host_unittest.cc
@@ -565,7 +565,8 @@
 
   // Start up the worker.
   status = SERVICE_WORKER_ERROR_ABORT;
-  version->StartWorker(base::Bind(&SaveStatusCallback, &called, &status));
+  version->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
+                       base::Bind(&SaveStatusCallback, &called, &status));
   base::RunLoop().RunUntilIdle();
 
   EXPECT_TRUE(called);
diff --git a/content/browser/service_worker/service_worker_fetch_dispatcher.cc b/content/browser/service_worker/service_worker_fetch_dispatcher.cc
index 2d7712b..d8091b8 100644
--- a/content/browser/service_worker/service_worker_fetch_dispatcher.cc
+++ b/content/browser/service_worker/service_worker_fetch_dispatcher.cc
@@ -13,15 +13,37 @@
 
 namespace content {
 
+namespace {
+using EventType = ServiceWorkerMetrics::EventType;
+EventType ResourceTypeToEventType(ResourceType resource_type) {
+  switch (resource_type) {
+    case RESOURCE_TYPE_MAIN_FRAME:
+      return EventType::FETCH_MAIN_FRAME;
+    case RESOURCE_TYPE_SUB_FRAME:
+      return EventType::FETCH_SUB_FRAME;
+    case RESOURCE_TYPE_SHARED_WORKER:
+      return EventType::FETCH_SHARED_WORKER;
+    case RESOURCE_TYPE_SERVICE_WORKER:
+    case RESOURCE_TYPE_LAST_TYPE:
+      NOTREACHED() << resource_type;
+      return EventType::FETCH_SUB_RESOURCE;
+    default:
+      return EventType::FETCH_SUB_RESOURCE;
+  }
+}
+}  // namespace
+
 ServiceWorkerFetchDispatcher::ServiceWorkerFetchDispatcher(
     scoped_ptr<ServiceWorkerFetchRequest> request,
     ServiceWorkerVersion* version,
+    ResourceType resource_type,
     const base::Closure& prepare_callback,
     const FetchCallback& fetch_callback)
     : version_(version),
       prepare_callback_(prepare_callback),
       fetch_callback_(fetch_callback),
       request_(std::move(request)),
+      resource_type_(resource_type),
       weak_factory_(this) {}
 
 ServiceWorkerFetchDispatcher::~ServiceWorkerFetchDispatcher() {}
@@ -47,6 +69,7 @@
     return;
   }
   version_->RunAfterStartWorker(
+      ResourceTypeToEventType(resource_type_),
       base::Bind(&ServiceWorkerFetchDispatcher::DispatchFetchEvent,
                  weak_factory_.GetWeakPtr()),
       base::Bind(&ServiceWorkerFetchDispatcher::DidFail,
diff --git a/content/browser/service_worker/service_worker_fetch_dispatcher.h b/content/browser/service_worker/service_worker_fetch_dispatcher.h
index a9af908a..efc3d29 100644
--- a/content/browser/service_worker/service_worker_fetch_dispatcher.h
+++ b/content/browser/service_worker/service_worker_fetch_dispatcher.h
@@ -11,6 +11,7 @@
 #include "content/common/content_export.h"
 #include "content/common/service_worker/service_worker_status_code.h"
 #include "content/common/service_worker/service_worker_types.h"
+#include "content/public/common/resource_type.h"
 
 namespace content {
 
@@ -27,6 +28,7 @@
 
   ServiceWorkerFetchDispatcher(scoped_ptr<ServiceWorkerFetchRequest> request,
                                ServiceWorkerVersion* version,
+                               ResourceType resource_type,
                                const base::Closure& prepare_callback,
                                const FetchCallback& fetch_callback);
   ~ServiceWorkerFetchDispatcher();
@@ -49,6 +51,7 @@
   base::Closure prepare_callback_;
   FetchCallback fetch_callback_;
   scoped_ptr<ServiceWorkerFetchRequest> request_;
+  ResourceType resource_type_;
   base::WeakPtrFactory<ServiceWorkerFetchDispatcher> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(ServiceWorkerFetchDispatcher);
diff --git a/content/browser/service_worker/service_worker_handle_unittest.cc b/content/browser/service_worker/service_worker_handle_unittest.cc
index 18f89fd..ae15a98e 100644
--- a/content/browser/service_worker/service_worker_handle_unittest.cc
+++ b/content/browser/service_worker/service_worker_handle_unittest.cc
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <vector>
+
 #include "base/macros.h"
 #include "base/run_loop.h"
 #include "content/browser/service_worker/embedded_worker_registry.h"
@@ -142,7 +144,8 @@
 
   // Start the worker, and then...
   ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
-  version_->StartWorker(CreateReceiverOnCurrentThread(&status));
+  version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
+                        CreateReceiverOnCurrentThread(&status));
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(SERVICE_WORKER_OK, status);
 
diff --git a/content/browser/service_worker/service_worker_job_unittest.cc b/content/browser/service_worker/service_worker_job_unittest.cc
index 0cbe471..f1175b2 100644
--- a/content/browser/service_worker/service_worker_job_unittest.cc
+++ b/content/browser/service_worker/service_worker_job_unittest.cc
@@ -643,7 +643,8 @@
   scoped_refptr<ServiceWorkerVersion> version = new ServiceWorkerVersion(
       registration.get(), script_url, 1L, helper_->context()->AsWeakPtr());
   ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
-  version->StartWorker(CreateReceiverOnCurrentThread(&status));
+  version->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
+                       CreateReceiverOnCurrentThread(&status));
   base::RunLoop().RunUntilIdle();
   ASSERT_EQ(SERVICE_WORKER_OK, status);
 
@@ -1420,7 +1421,8 @@
   void set_activate_event_result(blink::WebServiceWorkerEventResult result) {
     activate_event_result_ = result;
   }
-private:
+
+ private:
   base::Closure install_callback_;
   blink::WebServiceWorkerEventResult install_event_result_;
   blink::WebServiceWorkerEventResult activate_event_result_;
diff --git a/content/browser/service_worker/service_worker_metrics.cc b/content/browser/service_worker/service_worker_metrics.cc
index 3d0967b..2ee60c7d 100644
--- a/content/browser/service_worker/service_worker_metrics.cc
+++ b/content/browser/service_worker/service_worker_metrics.cc
@@ -68,11 +68,21 @@
       return "Service Port Connect";
     case EventType::MESSAGE:
       return "Message";
+    case EventType::FETCH_MAIN_FRAME:
+      return "Fetch Main Frame";
+    case EventType::FETCH_SUB_FRAME:
+      return "Fetch Sub Frame";
+    case EventType::FETCH_SHARED_WORKER:
+      return "Fetch Shared Worker";
+    case EventType::FETCH_SUB_RESOURCE:
+      return "Fetch Subresource";
+    case EventType::UNKNOWN:
+      return "Unknown";
     case EventType::NUM_TYPES:
       break;
   }
   NOTREACHED() << "Got unexpected event type: " << static_cast<int>(event_type);
-  return "Unknown";
+  return "error";
 }
 
 bool ServiceWorkerMetrics::ShouldExcludeSiteFromHistogram(Site site) {
@@ -147,10 +157,19 @@
 
 void ServiceWorkerMetrics::RecordStartWorkerStatus(
     ServiceWorkerStatusCode status,
+    EventType purpose,
     bool is_installed) {
   if (is_installed) {
     UMA_HISTOGRAM_ENUMERATION("ServiceWorker.StartWorker.Status", status,
                               SERVICE_WORKER_ERROR_MAX_VALUE);
+    UMA_HISTOGRAM_ENUMERATION("ServiceWorker.StartWorker.Purpose",
+                              static_cast<int>(purpose),
+                              static_cast<int>(EventType::NUM_TYPES));
+    if (status == SERVICE_WORKER_ERROR_TIMEOUT) {
+      UMA_HISTOGRAM_ENUMERATION(
+          "ServiceWorker.StartWorker.Timeout.StartPurpose",
+          static_cast<int>(purpose), static_cast<int>(EventType::NUM_TYPES));
+    }
   } else {
     UMA_HISTOGRAM_ENUMERATION("ServiceWorker.StartNewWorker.Status", status,
                               SERVICE_WORKER_ERROR_MAX_VALUE);
@@ -222,6 +241,10 @@
       UMA_HISTOGRAM_MEDIUM_TIMES("ServiceWorker.InstallEvent.Time", time);
       break;
     case EventType::FETCH:
+    case EventType::FETCH_MAIN_FRAME:
+    case EventType::FETCH_SUB_FRAME:
+    case EventType::FETCH_SHARED_WORKER:
+    case EventType::FETCH_SUB_RESOURCE:
       if (was_handled) {
         UMA_HISTOGRAM_MEDIUM_TIMES("ServiceWorker.FetchEvent.HasResponse.Time",
                                    time);
@@ -255,6 +278,7 @@
     case EventType::SERVICE_PORT_CONNECT:
       break;
 
+    case EventType::UNKNOWN:
     case EventType::NUM_TYPES:
       NOTREACHED() << "Invalid event type";
       break;
diff --git a/content/browser/service_worker/service_worker_metrics.h b/content/browser/service_worker/service_worker_metrics.h
index 6e4e3a4..6ad0663 100644
--- a/content/browser/service_worker/service_worker_metrics.h
+++ b/content/browser/service_worker/service_worker_metrics.h
@@ -76,7 +76,7 @@
   enum class EventType {
     ACTIVATE,
     INSTALL,
-    FETCH,
+    FETCH,  // Deprecated, use a more specific FETCH_ type.
     SYNC,
     NOTIFICATION_CLICK,
     PUSH,
@@ -84,8 +84,12 @@
     SERVICE_PORT_CONNECT,
     MESSAGE,
     NOTIFICATION_CLOSE,
+    FETCH_MAIN_FRAME,
+    FETCH_SUB_FRAME,
+    FETCH_SHARED_WORKER,
+    FETCH_SUB_RESOURCE,
+    UNKNOWN,  // Used when event type is not known.
     // Add new events to record here.
-
     NUM_TYPES
   };
 
@@ -122,6 +126,7 @@
   // Records the result of trying to start a worker. |is_installed| indicates
   // whether the version has been installed.
   static void RecordStartWorkerStatus(ServiceWorkerStatusCode status,
+                                      EventType purpose,
                                       bool is_installed);
 
   // Records the time taken to successfully start a worker. |is_installed|
diff --git a/content/browser/service_worker/service_worker_register_job.cc b/content/browser/service_worker/service_worker_register_job.cc
index ae7b436b..6f0155a 100644
--- a/content/browser/service_worker/service_worker_register_job.cc
+++ b/content/browser/service_worker/service_worker_register_job.cc
@@ -351,6 +351,7 @@
     new_version()->set_pause_after_download(false);
   }
   new_version()->StartWorker(
+      ServiceWorkerMetrics::EventType::INSTALL,
       base::Bind(&ServiceWorkerRegisterJob::OnStartWorkerFinished,
                  weak_factory_.GetWeakPtr()));
 }
@@ -414,6 +415,7 @@
 
   // "Fire an event named install..."
   new_version()->RunAfterStartWorker(
+      ServiceWorkerMetrics::EventType::INSTALL,
       base::Bind(&ServiceWorkerRegisterJob::DispatchInstallEvent,
                  weak_factory_.GetWeakPtr()),
       base::Bind(&ServiceWorkerRegisterJob::OnInstallFinished,
diff --git a/content/browser/service_worker/service_worker_registration.cc b/content/browser/service_worker/service_worker_registration.cc
index e1e6e5d..d24c8c93 100644
--- a/content/browser/service_worker/service_worker_registration.cc
+++ b/content/browser/service_worker/service_worker_registration.cc
@@ -287,6 +287,7 @@
 
   // "10. Queue a task to fire an event named activate..."
   activating_version->RunAfterStartWorker(
+      ServiceWorkerMetrics::EventType::ACTIVATE,
       base::Bind(&ServiceWorkerRegistration::DispatchActivateEvent, this,
                  activating_version),
       base::Bind(&ServiceWorkerRegistration::OnActivateEventFinished, this,
diff --git a/content/browser/service_worker/service_worker_url_request_job.cc b/content/browser/service_worker/service_worker_url_request_job.cc
index 092d72db..9afccc134 100644
--- a/content/browser/service_worker/service_worker_url_request_job.cc
+++ b/content/browser/service_worker/service_worker_url_request_job.cc
@@ -28,6 +28,7 @@
 #include "content/browser/streams/stream_registry.h"
 #include "content/common/resource_request_body.h"
 #include "content/common/service_worker/service_worker_types.h"
+#include "content/common/service_worker/service_worker_utils.h"
 #include "content/public/browser/blob_handle.h"
 #include "content/public/browser/resource_request_info.h"
 #include "content/public/browser/service_worker_context.h"
@@ -115,7 +116,7 @@
     FetchRequestMode request_mode,
     FetchCredentialsMode credentials_mode,
     FetchRedirectMode redirect_mode,
-    bool is_main_resource_load,
+    ResourceType resource_type,
     RequestContextType request_context_type,
     RequestContextFrameType frame_type,
     scoped_refptr<ResourceRequestBody> body,
@@ -133,7 +134,7 @@
       request_mode_(request_mode),
       credentials_mode_(credentials_mode),
       redirect_mode_(redirect_mode),
-      is_main_resource_load_(is_main_resource_load),
+      resource_type_(resource_type),
       request_context_type_(request_context_type),
       frame_type_(frame_type),
       fall_back_required_(false),
@@ -432,7 +433,7 @@
       // Send a fetch event to the ServiceWorker associated to the
       // provider_host.
       fetch_dispatcher_.reset(new ServiceWorkerFetchDispatcher(
-          CreateFetchRequest(), active_worker,
+          CreateFetchRequest(), active_worker, resource_type_,
           base::Bind(&ServiceWorkerURLRequestJob::DidPrepareFetchEvent,
                      weak_factory_.GetWeakPtr()),
           base::Bind(&ServiceWorkerURLRequestJob::DidDispatchFetchEvent,
@@ -455,7 +456,7 @@
   scoped_ptr<ServiceWorkerFetchRequest> request(
       new ServiceWorkerFetchRequest());
   request->mode = request_mode_;
-  request->is_main_resource_load = is_main_resource_load_;
+  request->is_main_resource_load = IsMainResourceLoad();
   request->request_context_type = request_context_type_;
   request->frame_type = frame_type_;
   request->url = request_->url();
@@ -570,7 +571,7 @@
     const ServiceWorkerResponse& response,
     const scoped_refptr<ServiceWorkerVersion>& version) {
   fetch_dispatcher_.reset();
-  ServiceWorkerMetrics::RecordFetchEventStatus(is_main_resource_load_, status);
+  ServiceWorkerMetrics::RecordFetchEventStatus(IsMainResourceLoad(), status);
 
   // Check if we're not orphaned.
   if (!request()) {
@@ -588,7 +589,7 @@
 
   if (status != SERVICE_WORKER_OK) {
     RecordResult(ServiceWorkerMetrics::REQUEST_JOB_ERROR_FETCH_EVENT_DISPATCH);
-    if (is_main_resource_load_) {
+    if (IsMainResourceLoad()) {
       // Using the service worker failed, so fallback to network.
       delegate_->MainResourceLoadFailed();
       response_type_ = FALLBACK_TO_NETWORK;
@@ -770,8 +771,7 @@
     return;
   }
   did_record_result_ = true;
-  ServiceWorkerMetrics::RecordURLRequestJobResult(is_main_resource_load_,
-                                                  result);
+  ServiceWorkerMetrics::RecordURLRequestJobResult(IsMainResourceLoad(), result);
   if (request())
     request()->net_log().AddEvent(RequestJobResultToNetEventType(result));
 }
@@ -785,7 +785,7 @@
     return;
   }
   RecordResult(ServiceWorkerMetrics::REQUEST_JOB_ERROR_RESPONSE_STATUS_ZERO);
-  ServiceWorkerMetrics::RecordStatusZeroResponseError(is_main_resource_load_,
+  ServiceWorkerMetrics::RecordStatusZeroResponseError(IsMainResourceLoad(),
                                                       error);
 }
 
@@ -840,4 +840,8 @@
                               worker_ready_time_);
 }
 
+bool ServiceWorkerURLRequestJob::IsMainResourceLoad() const {
+  return ServiceWorkerUtils::IsMainResourceType(resource_type_);
+}
+
 }  // namespace content
diff --git a/content/browser/service_worker/service_worker_url_request_job.h b/content/browser/service_worker/service_worker_url_request_job.h
index a3620dd..ae331bde 100644
--- a/content/browser/service_worker/service_worker_url_request_job.h
+++ b/content/browser/service_worker/service_worker_url_request_job.h
@@ -103,7 +103,7 @@
       FetchRequestMode request_mode,
       FetchCredentialsMode credentials_mode,
       FetchRedirectMode redirect_mode,
-      bool is_main_resource_load,
+      ResourceType resource_type,
       RequestContextType request_context_type,
       RequestContextFrameType frame_type,
       scoped_refptr<ResourceRequestBody> body,
@@ -227,6 +227,8 @@
   // calls it.
   void OnStartCompleted() const;
 
+  bool IsMainResourceLoad() const;
+
   // Not owned.
   Delegate* delegate_;
 
@@ -261,7 +263,7 @@
   FetchRequestMode request_mode_;
   FetchCredentialsMode credentials_mode_;
   FetchRedirectMode redirect_mode_;
-  const bool is_main_resource_load_;
+  const ResourceType resource_type_;
   RequestContextType request_context_type_;
   RequestContextFrameType frame_type_;
   bool fall_back_required_;
diff --git a/content/browser/service_worker/service_worker_url_request_job_unittest.cc b/content/browser/service_worker/service_worker_url_request_job_unittest.cc
index 39b07600c..6fbc6d6 100644
--- a/content/browser/service_worker/service_worker_url_request_job_unittest.cc
+++ b/content/browser/service_worker/service_worker_url_request_job_unittest.cc
@@ -174,7 +174,7 @@
         request, network_delegate, provider_host_->client_uuid(),
         blob_storage_context_, resource_context_, FETCH_REQUEST_MODE_NO_CORS,
         FETCH_CREDENTIALS_MODE_OMIT, FetchRedirectMode::FOLLOW_MODE,
-        true /* is_main_resource_load */, REQUEST_CONTEXT_TYPE_HYPERLINK,
+        RESOURCE_TYPE_MAIN_FRAME, REQUEST_CONTEXT_TYPE_HYPERLINK,
         REQUEST_CONTEXT_FRAME_TYPE_TOP_LEVEL,
         scoped_refptr<ResourceRequestBody>(), ServiceWorkerFetchType::FETCH,
         delegate_);
diff --git a/content/browser/service_worker/service_worker_version.cc b/content/browser/service_worker/service_worker_version.cc
index 6c427f25..76b73bb 100644
--- a/content/browser/service_worker/service_worker_version.cc
+++ b/content/browser/service_worker/service_worker_version.cc
@@ -303,7 +303,11 @@
           kDestructedStartingWorkerTimeoutThresholdSeconds)) {
     DCHECK(timeout_timer_.IsRunning());
     DCHECK(!embedded_worker_->devtools_attached());
-    RecordStartWorkerResult(SERVICE_WORKER_ERROR_TIMEOUT);
+
+    // RecordStartWorkerResult must be in start_callbacks_.
+    DCHECK(!start_callbacks_.empty());
+    RecordStartWorkerResult(ServiceWorkerMetrics::EventType::UNKNOWN,
+                            SERVICE_WORKER_ERROR_TIMEOUT);
   }
 
   if (context_)
@@ -361,20 +365,21 @@
   return info;
 }
 
-void ServiceWorkerVersion::StartWorker(const StatusCallback& callback) {
+void ServiceWorkerVersion::StartWorker(ServiceWorkerMetrics::EventType purpose,
+                                       const StatusCallback& callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   if (!context_) {
-    RecordStartWorkerResult(SERVICE_WORKER_ERROR_ABORT);
+    RecordStartWorkerResult(purpose, SERVICE_WORKER_ERROR_ABORT);
     RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_ABORT));
     return;
   }
   if (is_redundant()) {
-    RecordStartWorkerResult(SERVICE_WORKER_ERROR_REDUNDANT);
+    RecordStartWorkerResult(purpose, SERVICE_WORKER_ERROR_REDUNDANT);
     RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_REDUNDANT));
     return;
   }
   if (IsDisabled()) {
-    RecordStartWorkerResult(SERVICE_WORKER_ERROR_DISABLED_WORKER);
+    RecordStartWorkerResult(purpose, SERVICE_WORKER_ERROR_DISABLED_WORKER);
     RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_DISABLED_WORKER));
 
     // Show a message in DevTools for developers.
@@ -390,7 +395,7 @@
   if (context_->wrapper()->resource_context() &&
       !GetContentClient()->browser()->AllowServiceWorker(
           scope_, scope_, context_->wrapper()->resource_context(), -1, -1)) {
-    RecordStartWorkerResult(SERVICE_WORKER_ERROR_DISALLOWED);
+    RecordStartWorkerResult(purpose, SERVICE_WORKER_ERROR_DISALLOWED);
     RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_DISALLOWED));
     return;
   }
@@ -400,11 +405,9 @@
   // Ensure the live registration during starting worker so that the worker can
   // get associated with it in SWDispatcherHost::OnSetHostedVersionId().
   context_->storage()->FindRegistrationForId(
-      registration_id_,
-      scope_.GetOrigin(),
+      registration_id_, scope_.GetOrigin(),
       base::Bind(&ServiceWorkerVersion::DidEnsureLiveRegistrationForStartWorker,
-                 weak_factory_.GetWeakPtr(),
-                 callback));
+                 weak_factory_.GetWeakPtr(), purpose, callback));
 }
 
 void ServiceWorkerVersion::StopWorker(const StatusCallback& callback) {
@@ -514,6 +517,7 @@
 }
 
 void ServiceWorkerVersion::RunAfterStartWorker(
+    ServiceWorkerMetrics::EventType purpose,
     const base::Closure& task,
     const StatusCallback& error_callback) {
   if (running_status() == RUNNING) {
@@ -521,7 +525,8 @@
     task.Run();
     return;
   }
-  StartWorker(base::Bind(&RunTaskAfterStartWorker, weak_factory_.GetWeakPtr(),
+  StartWorker(purpose,
+              base::Bind(&RunTaskAfterStartWorker, weak_factory_.GetWeakPtr(),
                          error_callback, task));
 }
 
@@ -543,12 +548,13 @@
   OnBeginEvent();
   if (running_status() != RUNNING) {
     // Schedule calling this method after starting the worker.
-    StartWorker(base::Bind(
-        &RunTaskAfterStartWorker, weak_factory_.GetWeakPtr(),
-        base::Bind(&RunErrorMessageCallback, sent_message_ports, callback),
-        base::Bind(&self::DispatchMessageEventInternal,
-                   weak_factory_.GetWeakPtr(), message, sent_message_ports,
-                   callback)));
+    StartWorker(ServiceWorkerMetrics::EventType::MESSAGE,
+                base::Bind(&RunTaskAfterStartWorker, weak_factory_.GetWeakPtr(),
+                           base::Bind(&RunErrorMessageCallback,
+                                      sent_message_ports, callback),
+                           base::Bind(&self::DispatchMessageEventInternal,
+                                      weak_factory_.GetWeakPtr(), message,
+                                      sent_message_ports, callback)));
     return;
   }
 
@@ -578,12 +584,13 @@
 
   if (running_status() != RUNNING) {
     // Schedule calling this method after starting the worker.
-    StartWorker(base::Bind(
-        &RunTaskAfterStartWorker, weak_factory_.GetWeakPtr(),
-        base::Bind(&RunErrorMessageCallback, sent_message_ports, callback),
-        base::Bind(&self::DispatchCrossOriginMessageEvent,
-                   weak_factory_.GetWeakPtr(), client, message,
-                   sent_message_ports, callback)));
+    StartWorker(ServiceWorkerMetrics::EventType::MESSAGE,
+                base::Bind(&RunTaskAfterStartWorker, weak_factory_.GetWeakPtr(),
+                           base::Bind(&RunErrorMessageCallback,
+                                      sent_message_ports, callback),
+                           base::Bind(&self::DispatchCrossOriginMessageEvent,
+                                      weak_factory_.GetWeakPtr(), client,
+                                      message, sent_message_ports, callback)));
     return;
   }
 
@@ -1276,6 +1283,7 @@
 }
 
 void ServiceWorkerVersion::DidEnsureLiveRegistrationForStartWorker(
+    ServiceWorkerMetrics::EventType purpose,
     const StatusCallback& callback,
     ServiceWorkerStatusCode status,
     const scoped_refptr<ServiceWorkerRegistration>& registration) {
@@ -1292,12 +1300,12 @@
     }
   }
   if (status != SERVICE_WORKER_OK) {
-    RecordStartWorkerResult(status);
+    RecordStartWorkerResult(purpose, status);
     RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_START_WORKER_FAILED));
     return;
   }
   if (is_redundant()) {
-    RecordStartWorkerResult(SERVICE_WORKER_ERROR_REDUNDANT);
+    RecordStartWorkerResult(purpose, SERVICE_WORKER_ERROR_REDUNDANT);
     RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_REDUNDANT));
     return;
   }
@@ -1316,7 +1324,7 @@
       if (start_callbacks_.empty()) {
         start_callbacks_.push_back(
             base::Bind(&ServiceWorkerVersion::RecordStartWorkerResult,
-                       weak_factory_.GetWeakPtr()));
+                       weak_factory_.GetWeakPtr(), purpose));
       }
       break;
   }
@@ -1508,6 +1516,7 @@
 }
 
 void ServiceWorkerVersion::RecordStartWorkerResult(
+    ServiceWorkerMetrics::EventType purpose,
     ServiceWorkerStatusCode status) {
   base::TimeTicks start_time = start_time_;
   ClearTick(&start_time_);
@@ -1515,7 +1524,7 @@
   if (context_)
     context_->UpdateVersionFailureCount(version_id_, status);
 
-  ServiceWorkerMetrics::RecordStartWorkerStatus(status,
+  ServiceWorkerMetrics::RecordStartWorkerStatus(status, purpose,
                                                 IsInstalled(prestart_status_));
 
   if (status == SERVICE_WORKER_OK && !start_time.is_null() &&
diff --git a/content/browser/service_worker/service_worker_version.h b/content/browser/service_worker/service_worker_version.h
index 9fcc5ff..a38a487 100644
--- a/content/browser/service_worker/service_worker_version.h
+++ b/content/browser/service_worker/service_worker_version.h
@@ -164,7 +164,9 @@
 
   // Starts an embedded worker for this version.
   // This returns OK (success) if the worker is already running.
-  void StartWorker(const StatusCallback& callback);
+  // |purpose| is recorded in UMA.
+  void StartWorker(ServiceWorkerMetrics::EventType purpose,
+                   const StatusCallback& callback);
 
   // Stops an embedded worker for this version.
   // This returns OK (success) if the worker is already stopped.
@@ -184,7 +186,9 @@
   // worker is running, or |error_callback| if starting the worker failed.
   // If the worker is already running, |task| is executed synchronously (before
   // this method returns).
-  void RunAfterStartWorker(const base::Closure& task,
+  // |purpose| is used for UMA.
+  void RunAfterStartWorker(ServiceWorkerMetrics::EventType purpose,
+                           const base::Closure& task,
                            const StatusCallback& error_callback);
 
   // Call this while the worker is running before dispatching an event to the
@@ -555,6 +559,7 @@
                                     const std::vector<url::Origin>& origins);
 
   void DidEnsureLiveRegistrationForStartWorker(
+      ServiceWorkerMetrics::EventType purpose,
       const StatusCallback& callback,
       ServiceWorkerStatusCode status,
       const scoped_refptr<ServiceWorkerRegistration>& registration);
@@ -585,7 +590,8 @@
 
   // RecordStartWorkerResult is added as a start callback by StartTimeoutTimer
   // and records metrics about startup.
-  void RecordStartWorkerResult(ServiceWorkerStatusCode status);
+  void RecordStartWorkerResult(ServiceWorkerMetrics::EventType purpose,
+                               ServiceWorkerStatusCode status);
 
   bool MaybeTimeOutRequest(const RequestInfo& info);
   void SetAllRequestExpirations(const base::TimeTicks& expiration);
diff --git a/content/browser/service_worker/service_worker_version_unittest.cc b/content/browser/service_worker/service_worker_version_unittest.cc
index 8744b98d..628d625 100644
--- a/content/browser/service_worker/service_worker_version_unittest.cc
+++ b/content/browser/service_worker/service_worker_version_unittest.cc
@@ -252,7 +252,7 @@
 
     // Make sure worker is running.
     scoped_refptr<MessageLoopRunner> runner(new MessageLoopRunner);
-    version_->RunAfterStartWorker(runner->QuitClosure(),
+    version_->RunAfterStartWorker(event_type, runner->QuitClosure(),
                                   CreateReceiverOnCurrentThread(&status));
     runner->Run();
     EXPECT_EQ(SERVICE_WORKER_ERROR_MAX_VALUE, status);
@@ -387,15 +387,18 @@
   ServiceWorkerStatusCode status1 = SERVICE_WORKER_ERROR_FAILED;
   ServiceWorkerStatusCode status2 = SERVICE_WORKER_ERROR_FAILED;
   ServiceWorkerStatusCode status3 = SERVICE_WORKER_ERROR_FAILED;
-  version_->StartWorker(CreateReceiverOnCurrentThread(&status1));
-  version_->StartWorker(CreateReceiverOnCurrentThread(&status2));
+  version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
+                        CreateReceiverOnCurrentThread(&status1));
+  version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
+                        CreateReceiverOnCurrentThread(&status2));
 
   EXPECT_EQ(ServiceWorkerVersion::STARTING, version_->running_status());
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status());
 
   // Call StartWorker() after it's started.
-  version_->StartWorker(CreateReceiverOnCurrentThread(&status3));
+  version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
+                        CreateReceiverOnCurrentThread(&status3));
   base::RunLoop().RunUntilIdle();
 
   // All should just succeed.
@@ -422,7 +425,8 @@
   status2 = SERVICE_WORKER_ERROR_FAILED;
   status3 = SERVICE_WORKER_ERROR_FAILED;
 
-  version_->StartWorker(CreateReceiverOnCurrentThread(&status1));
+  version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
+                        CreateReceiverOnCurrentThread(&status1));
 
   EXPECT_EQ(ServiceWorkerVersion::STARTING, version_->running_status());
   base::RunLoop().RunUntilIdle();
@@ -433,7 +437,8 @@
   version_->StopWorker(CreateReceiverOnCurrentThread(&status2));
 
   // And try calling StartWorker while StopWorker is in queue.
-  version_->StartWorker(CreateReceiverOnCurrentThread(&status3));
+  version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
+                        CreateReceiverOnCurrentThread(&status3));
 
   EXPECT_EQ(ServiceWorkerVersion::STOPPING, version_->running_status());
   base::RunLoop().RunUntilIdle();
@@ -468,7 +473,8 @@
 TEST_F(ServiceWorkerVersionTest, StartUnregisteredButStillLiveWorker) {
   // Start the worker.
   ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
-  version_->StartWorker(CreateReceiverOnCurrentThread(&status));
+  version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
+                        CreateReceiverOnCurrentThread(&status));
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status());
   version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
@@ -501,7 +507,8 @@
 TEST_F(ServiceWorkerVersionTest, ReceiveMessageFromWorker) {
   // Start worker.
   ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
-  version_->StartWorker(CreateReceiverOnCurrentThread(&status));
+  version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
+                        CreateReceiverOnCurrentThread(&status));
   EXPECT_EQ(ServiceWorkerVersion::STARTING, version_->running_status());
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(SERVICE_WORKER_OK, status);
@@ -592,7 +599,8 @@
 
   // Verify the timer is running after the worker is started.
   ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
-  version_->StartWorker(CreateReceiverOnCurrentThread(&status));
+  version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
+                        CreateReceiverOnCurrentThread(&status));
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(SERVICE_WORKER_OK, status);
   EXPECT_TRUE(version_->timeout_timer_.IsRunning());
@@ -607,7 +615,8 @@
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(SERVICE_WORKER_OK, status);
   status = SERVICE_WORKER_ERROR_FAILED;
-  version_->StartWorker(CreateReceiverOnCurrentThread(&status));
+  version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
+                        CreateReceiverOnCurrentThread(&status));
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(SERVICE_WORKER_OK, status);
   EXPECT_TRUE(version_->timeout_timer_.IsRunning());
@@ -658,7 +667,8 @@
 
 TEST_F(ServiceWorkerVersionTest, SetDevToolsAttached) {
   ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
-  version_->StartWorker(CreateReceiverOnCurrentThread(&status));
+  version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
+                        CreateReceiverOnCurrentThread(&status));
 
   ASSERT_EQ(ServiceWorkerVersion::STARTING, version_->running_status());
 
@@ -690,7 +700,8 @@
   version_->AddListener(&listener);
 
   ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
-  version_->StartWorker(CreateReceiverOnCurrentThread(&status));
+  version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
+                        CreateReceiverOnCurrentThread(&status));
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(SERVICE_WORKER_OK, status);
   EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status());
@@ -782,10 +793,10 @@
 
   // Stale time is not deferred.
   version_->RunAfterStartWorker(
-      base::Bind(&base::DoNothing),
+      ServiceWorkerMetrics::EventType::UNKNOWN, base::Bind(&base::DoNothing),
       base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
   version_->RunAfterStartWorker(
-      base::Bind(&base::DoNothing),
+      ServiceWorkerMetrics::EventType::UNKNOWN, base::Bind(&base::DoNothing),
       base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(stale_time, version_->stale_time_);
@@ -809,7 +820,8 @@
   ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_NETWORK;  // dummy value
   version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
 
-  version_->StartWorker(base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
+  version_->StartWorker(ServiceWorkerMetrics::EventType::FETCH,
+                        base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
   base::RunLoop().RunUntilIdle();
 
   // Create a request.
@@ -836,7 +848,8 @@
   ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_NETWORK;  // dummy value
   version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
 
-  version_->StartWorker(base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
+  version_->StartWorker(ServiceWorkerMetrics::EventType::SYNC,
+                        base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
   base::RunLoop().RunUntilIdle();
 
   // Create a request that should expire Now().
@@ -861,7 +874,8 @@
   ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_NETWORK;  // dummy value
   version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
 
-  version_->StartWorker(base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
+  version_->StartWorker(ServiceWorkerMetrics::EventType::SYNC,
+                        base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
   base::RunLoop().RunUntilIdle();
 
   // Create a request that should expire Now().
@@ -889,7 +903,8 @@
       SERVICE_WORKER_ERROR_NETWORK;  // dummy value
   version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
 
-  version_->StartWorker(base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
+  version_->StartWorker(ServiceWorkerMetrics::EventType::FETCH,
+                        base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
   base::RunLoop().RunUntilIdle();
 
   // Create a fetch request that should expire sometime later.
@@ -932,8 +947,8 @@
 
 TEST_F(ServiceWorkerFailToStartTest, RendererCrash) {
   ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_NETWORK;  // dummy value
-  version_->StartWorker(
-      CreateReceiverOnCurrentThread(&status));
+  version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
+                        CreateReceiverOnCurrentThread(&status));
   base::RunLoop().RunUntilIdle();
 
   // Callback has not completed yet.
@@ -957,7 +972,8 @@
   ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_NETWORK;  // dummy value
 
   // Start starting the worker.
-  version_->StartWorker(CreateReceiverOnCurrentThread(&status));
+  version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
+                        CreateReceiverOnCurrentThread(&status));
   base::RunLoop().RunUntilIdle();
 
   // Callback has not completed yet.
@@ -981,7 +997,8 @@
 TEST_F(ServiceWorkerStallInStoppingTest, DetachThenStart) {
   // Start a worker.
   ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
-  version_->StartWorker(CreateReceiverOnCurrentThread(&status));
+  version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
+                        CreateReceiverOnCurrentThread(&status));
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(SERVICE_WORKER_OK, status);
   EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status());
@@ -1010,7 +1027,8 @@
 
   // Try to start the worker again. It should work.
   status = SERVICE_WORKER_ERROR_FAILED;
-  version_->StartWorker(CreateReceiverOnCurrentThread(&status));
+  version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
+                        CreateReceiverOnCurrentThread(&status));
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(SERVICE_WORKER_OK, status);
   EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status());
@@ -1027,7 +1045,8 @@
 TEST_F(ServiceWorkerStallInStoppingTest, DetachThenRestart) {
   // Start a worker.
   ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
-  version_->StartWorker(CreateReceiverOnCurrentThread(&status));
+  version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
+                        CreateReceiverOnCurrentThread(&status));
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(SERVICE_WORKER_OK, status);
   EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status());
@@ -1039,7 +1058,8 @@
 
   // Worker is now stalled in stopping. Add a start worker requset.
   ServiceWorkerStatusCode start_status = SERVICE_WORKER_ERROR_FAILED;
-  version_->StartWorker(CreateReceiverOnCurrentThread(&start_status));
+  version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
+                        CreateReceiverOnCurrentThread(&start_status));
 
   // Simulate timeout. The worker should stop and get restarted.
   EXPECT_TRUE(version_->timeout_timer_.IsRunning());
@@ -1058,7 +1078,8 @@
   version_->SetStatus(ServiceWorkerVersion::INSTALLING);
   // Start a worker.
   ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
-  version_->StartWorker(CreateReceiverOnCurrentThread(&status));
+  version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
+                        CreateReceiverOnCurrentThread(&status));
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(SERVICE_WORKER_OK, status);
   EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status());
@@ -1133,7 +1154,8 @@
   ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_NETWORK;  // dummy value
 
   version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
-  version_->StartWorker(CreateReceiverOnCurrentThread(&status));
+  version_->StartWorker(ServiceWorkerMetrics::EventType::SYNC,
+                        CreateReceiverOnCurrentThread(&status));
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(SERVICE_WORKER_OK, status);
   EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status());
@@ -1166,7 +1188,8 @@
   ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_NETWORK;  // dummy value
 
   version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
-  version_->StartWorker(CreateReceiverOnCurrentThread(&status));
+  version_->StartWorker(ServiceWorkerMetrics::EventType::SYNC,
+                        CreateReceiverOnCurrentThread(&status));
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(SERVICE_WORKER_OK, status);
   EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status());
@@ -1190,7 +1213,8 @@
   ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_NETWORK;  // dummy value
 
   version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
-  version_->StartWorker(CreateReceiverOnCurrentThread(&status));
+  version_->StartWorker(ServiceWorkerMetrics::EventType::SYNC,
+                        CreateReceiverOnCurrentThread(&status));
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(SERVICE_WORKER_OK, status);
   EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status());
@@ -1215,7 +1239,8 @@
 
   // Activate and start worker.
   version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
-  version_->StartWorker(CreateReceiverOnCurrentThread(&status));
+  version_->StartWorker(ServiceWorkerMetrics::EventType::SYNC,
+                        CreateReceiverOnCurrentThread(&status));
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(SERVICE_WORKER_OK, status);
   EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status());
@@ -1265,16 +1290,19 @@
   int64_t id = version_->version_id();
   set_start_mode(MessageReceiverDisallowStart::StartMode::FAIL);
   // Fail once.
-  version_->StartWorker(CreateReceiverOnCurrentThread(&status));
+  version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
+                        CreateReceiverOnCurrentThread(&status));
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(1, context->GetVersionFailureCount(id));
   // Fail again.
-  version_->StartWorker(CreateReceiverOnCurrentThread(&status));
+  version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
+                        CreateReceiverOnCurrentThread(&status));
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(2, context->GetVersionFailureCount(id));
   // Succeed. It should choose the "new process".
   set_start_mode(MessageReceiverDisallowStart::StartMode::SUCCEED);
-  version_->StartWorker(CreateReceiverOnCurrentThread(&status));
+  version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
+                        CreateReceiverOnCurrentThread(&status));
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(helper_->new_render_process_id(),
             version_->embedded_worker()->process_id());
@@ -1285,22 +1313,26 @@
   // (2) Fail three times. The worker should be disabled.
   set_start_mode(MessageReceiverDisallowStart::StartMode::FAIL);
   // Fail once.
-  version_->StartWorker(CreateReceiverOnCurrentThread(&status));
+  version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
+                        CreateReceiverOnCurrentThread(&status));
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(1, context->GetVersionFailureCount(id));
   // Fail again.
-  version_->StartWorker(CreateReceiverOnCurrentThread(&status));
+  version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
+                        CreateReceiverOnCurrentThread(&status));
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(2, context->GetVersionFailureCount(id));
   // Fail again.
-  version_->StartWorker(CreateReceiverOnCurrentThread(&status));
+  version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
+                        CreateReceiverOnCurrentThread(&status));
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(3, context->GetVersionFailureCount(id));
 
   // The worker should be disabled.
   EXPECT_TRUE(version_->IsDisabled());
   set_start_mode(MessageReceiverDisallowStart::StartMode::SUCCEED);
-  version_->StartWorker(CreateReceiverOnCurrentThread(&status));
+  version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
+                        CreateReceiverOnCurrentThread(&status));
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(SERVICE_WORKER_ERROR_DISABLED_WORKER, status);
   EXPECT_EQ(ServiceWorkerVersion::STOPPED, version_->running_status());
@@ -1319,7 +1351,8 @@
 
   // Activate and start worker.
   version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
-  version_->StartWorker(CreateReceiverOnCurrentThread(&status));
+  version_->StartWorker(ServiceWorkerMetrics::EventType::SYNC,
+                        CreateReceiverOnCurrentThread(&status));
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(SERVICE_WORKER_OK, status);
   EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status());
@@ -1396,7 +1429,8 @@
 
   // Activate and start worker.
   version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
-  version_->StartWorker(CreateReceiverOnCurrentThread(&status));
+  version_->StartWorker(ServiceWorkerMetrics::EventType::SYNC,
+                        CreateReceiverOnCurrentThread(&status));
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(SERVICE_WORKER_OK, status);
   EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status());
@@ -1432,7 +1466,8 @@
 
   // Activate and start worker.
   version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
-  version_->StartWorker(CreateReceiverOnCurrentThread(&status));
+  version_->StartWorker(ServiceWorkerMetrics::EventType::SYNC,
+                        CreateReceiverOnCurrentThread(&status));
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(SERVICE_WORKER_OK, status);
   EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status());
diff --git a/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc b/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc
index 3a1745f..028e874d 100644
--- a/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc
+++ b/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc
@@ -249,7 +249,7 @@
       gles2_helper_.get(), gles2_share_group.get(), transfer_buffer_.get(),
       bind_generates_resources, lose_context_when_out_of_memory_,
       support_client_side_arrays, command_buffer_.get()));
-  setGLInterface(real_gl_.get());
+  SetGLInterface(real_gl_.get());
 
   if (!real_gl_->Initialize(
       mem_limits_.start_transfer_buffer_size,
@@ -266,7 +266,7 @@
   if (base::CommandLine::ForCurrentProcess()->HasSwitch(
           switches::kEnableGpuClientTracing)) {
     trace_gl_.reset(new gpu::gles2::GLES2TraceImplementation(GetGLInterface()));
-    setGLInterface(trace_gl_.get());
+    SetGLInterface(trace_gl_.get());
   }
   return true;
 }
@@ -296,7 +296,7 @@
     // issued on this context might not be visible to other contexts in the
     // share group.
     gl->Flush();
-    setGLInterface(NULL);
+    SetGLInterface(nullptr);
   }
 
   trace_gl_.reset();
@@ -306,7 +306,7 @@
   real_gl_.reset();
   command_buffer_.reset();
 
-  host_ = NULL;
+  host_ = nullptr;
 }
 
 gpu::ContextSupport*
diff --git a/content/renderer/shared_worker/embedded_shared_worker_content_settings_client_proxy.cc b/content/renderer/shared_worker/embedded_shared_worker_content_settings_client_proxy.cc
index ebeff78..97b5063 100644
--- a/content/renderer/shared_worker/embedded_shared_worker_content_settings_client_proxy.cc
+++ b/content/renderer/shared_worker/embedded_shared_worker_content_settings_client_proxy.cc
@@ -27,18 +27,6 @@
     ~EmbeddedSharedWorkerContentSettingsClientProxy() {
 }
 
-bool EmbeddedSharedWorkerContentSettingsClientProxy::allowDatabase(
-    const blink::WebString& name,
-    const blink::WebString& display_name,
-    unsigned long estimated_size) {
-  if (is_unique_origin_)
-    return false;
-  bool result = false;
-  thread_safe_sender_->Send(new WorkerProcessHostMsg_AllowDatabase(
-      routing_id_, origin_url_, name, display_name, &result));
-  return result;
-}
-
 bool
 EmbeddedSharedWorkerContentSettingsClientProxy::requestFileSystemAccessSync() {
   if (is_unique_origin_)
diff --git a/content/renderer/shared_worker/embedded_shared_worker_content_settings_client_proxy.h b/content/renderer/shared_worker/embedded_shared_worker_content_settings_client_proxy.h
index e87e30d..b93d989a 100644
--- a/content/renderer/shared_worker/embedded_shared_worker_content_settings_client_proxy.h
+++ b/content/renderer/shared_worker/embedded_shared_worker_content_settings_client_proxy.h
@@ -27,9 +27,6 @@
   ~EmbeddedSharedWorkerContentSettingsClientProxy() override;
 
   // WebWorkerContentSettingsClientProxy overrides.
-  bool allowDatabase(const blink::WebString& name,
-                     const blink::WebString& display_name,
-                     unsigned long estimated_size) override;
   bool requestFileSystemAccessSync() override;
   bool allowIndexedDB(const blink::WebString& name) override;
 
diff --git a/content/renderer/webgraphicscontext3d_provider_impl.cc b/content/renderer/webgraphicscontext3d_provider_impl.cc
index 855bd3d..1fcdb63 100644
--- a/content/renderer/webgraphicscontext3d_provider_impl.cc
+++ b/content/renderer/webgraphicscontext3d_provider_impl.cc
@@ -16,9 +16,15 @@
 WebGraphicsContext3DProviderImpl::~WebGraphicsContext3DProviderImpl() {}
 
 blink::WebGraphicsContext3D* WebGraphicsContext3DProviderImpl::context3d() {
+  DCHECK_EQ(!!provider_->WebContext3D(), !!provider_->ContextGL());
   return provider_->WebContext3D();
 }
 
+gpu::gles2::GLES2Interface* WebGraphicsContext3DProviderImpl::contextGL() {
+  DCHECK_EQ(!!provider_->WebContext3D(), !!provider_->ContextGL());
+  return provider_->ContextGL();
+}
+
 GrContext* WebGraphicsContext3DProviderImpl::grContext() {
   return provider_->GrContext();
 }
diff --git a/content/renderer/webgraphicscontext3d_provider_impl.h b/content/renderer/webgraphicscontext3d_provider_impl.h
index 769dd56..de155bd 100644
--- a/content/renderer/webgraphicscontext3d_provider_impl.h
+++ b/content/renderer/webgraphicscontext3d_provider_impl.h
@@ -14,6 +14,12 @@
 class ContextProviderWebContext;
 }
 
+namespace gpu {
+namespace gles2 {
+class GLES2Interface;
+}
+}
+
 namespace content {
 
 class CONTENT_EXPORT WebGraphicsContext3DProviderImpl
@@ -25,6 +31,7 @@
 
   // WebGraphicsContext3DProvider implementation.
   blink::WebGraphicsContext3D* context3d() override;
+  gpu::gles2::GLES2Interface* contextGL() override;
   GrContext* grContext() override;
 
  private:
diff --git a/content/test/gpu/generate_buildbot_json.py b/content/test/gpu/generate_buildbot_json.py
index fb60b51..36ab240e 100755
--- a/content/test/gpu/generate_buildbot_json.py
+++ b/content/test/gpu/generate_buildbot_json.py
@@ -212,6 +212,17 @@
       'swarming': False,
       'os_type': 'win',
     },
+    'Win7 Release (NVIDIA GeForce 730)': {
+      'swarming_dimensions': {
+        'gpu': '10de:0f02',
+        'os': 'Windows-2008ServerR2-SP1'
+      },
+      'build_config': 'Release',
+      # This bot is a one-off and doesn't have similar slaves in the
+      # swarming pool.
+      'swarming': False,
+      'os_type': 'win',
+    },
     'Win7 x64 Release (NVIDIA)': {
       'swarming_dimensions': {
         'gpu': '10de:104a',
@@ -341,6 +352,17 @@
       'swarming': False,
       'os_type': 'linux',
     },
+    'Linux Release (NVIDIA GeForce 730)': {
+      'swarming_dimensions': {
+        'gpu': '10de:0f02',
+        'os': 'Linux'
+      },
+      'build_config': 'Release',
+      # This bot is a one-off and doesn't have similar slaves in the
+      # swarming pool.
+      'swarming': False,
+      'os_type': 'linux',
+    },
     'Linux Debug (NVIDIA)': {
       'swarming_dimensions': {
         'gpu': '10de:104a',
diff --git a/google_apis/gcm/BUILD.gn b/google_apis/gcm/BUILD.gn
index f63aefb..6073e1d 100644
--- a/google_apis/gcm/BUILD.gn
+++ b/google_apis/gcm/BUILD.gn
@@ -106,21 +106,23 @@
 }
 
 # A standalone MCS (mobile connection server) client.
-executable("mcs_probe") {
-  testonly = true
-  sources = [
-    "tools/mcs_probe.cc",
-  ]
+if (!is_ios) {
+  executable("mcs_probe") {
+    testonly = true
+    sources = [
+      "tools/mcs_probe.cc",
+    ]
 
-  deps = [
-    ":gcm",
-    ":test_support",
-    "//base",
-    "//build/config/sanitizers:deps",
-    "//net",
-    "//net:test_support",
-    "//third_party/protobuf:protobuf_lite",
-  ]
+    deps = [
+      ":gcm",
+      ":test_support",
+      "//base",
+      "//build/config/sanitizers:deps",
+      "//net",
+      "//net:test_support",
+      "//third_party/protobuf:protobuf_lite",
+    ]
+  }
 }
 
 test("gcm_unit_tests") {
diff --git a/gpu/blink/webgraphicscontext3d_impl.cc b/gpu/blink/webgraphicscontext3d_impl.cc
index 64a9f96..d260e94 100644
--- a/gpu/blink/webgraphicscontext3d_impl.cc
+++ b/gpu/blink/webgraphicscontext3d_impl.cc
@@ -1216,14 +1216,14 @@
   gl_->WaitSync(reinterpret_cast<GLsync>(sync), flags, timeout);
 }
 
-bool WebGraphicsContext3DImpl::isContextLost() {
-  return getGraphicsResetStatusARB() != GL_NO_ERROR;
-}
-
 blink::WGC3Denum WebGraphicsContext3DImpl::getGraphicsResetStatusARB() {
   return gl_->GetGraphicsResetStatusKHR();
 }
 
+::gpu::gles2::GLES2Interface* WebGraphicsContext3DImpl::getGLES2Interface() {
+  return gl_;
+}
+
 ::gpu::gles2::GLES2ImplementationErrorMessageCallback*
     WebGraphicsContext3DImpl::getErrorMessageCallback() {
   if (!client_error_message_callback_) {
diff --git a/gpu/blink/webgraphicscontext3d_impl.h b/gpu/blink/webgraphicscontext3d_impl.h
index 91881ba..ab5ab3a 100644
--- a/gpu/blink/webgraphicscontext3d_impl.h
+++ b/gpu/blink/webgraphicscontext3d_impl.h
@@ -937,9 +937,11 @@
                 blink::WGC3Dbitfield flags,
                 blink::WGC3Duint64 timeout) override;
 
-  bool isContextLost() override;
   blink::WGC3Denum getGraphicsResetStatusARB() override;
 
+  // WebGraphicsContext3D implementation.
+  ::gpu::gles2::GLES2Interface* getGLES2Interface() override;
+
   ::gpu::gles2::GLES2Interface* GetGLInterface() {
     return gl_;
   }
@@ -959,9 +961,7 @@
       getErrorMessageCallback();
   virtual void OnErrorMessage(const std::string& message, int id);
 
-  void setGLInterface(::gpu::gles2::GLES2Interface* gl) {
-    gl_ = gl;
-  }
+  void SetGLInterface(::gpu::gles2::GLES2Interface* gl) { gl_ = gl; }
 
   bool initialized_;
   bool initialize_failed_;
diff --git a/gpu/blink/webgraphicscontext3d_in_process_command_buffer_impl.cc b/gpu/blink/webgraphicscontext3d_in_process_command_buffer_impl.cc
index cc18157..5daf178 100644
--- a/gpu/blink/webgraphicscontext3d_in_process_command_buffer_impl.cc
+++ b/gpu/blink/webgraphicscontext3d_in_process_command_buffer_impl.cc
@@ -136,7 +136,7 @@
   }
 
   real_gl_ = context_->GetImplementation();
-  setGLInterface(real_gl_);
+  SetGLInterface(real_gl_);
 
   real_gl_->TraceBeginCHROMIUM("WebGraphicsContext3D",
                                "InProcessContext");
@@ -149,7 +149,9 @@
 WebGraphicsContext3DInProcessCommandBufferImpl::InitializeOnCurrentThread() {
   if (!MaybeInitializeGL())
     return false;
-  return context_ && !isContextLost();
+  return context_ &&
+         context_->GetImplementation()->GetGraphicsResetStatusKHR() ==
+             GL_NO_ERROR;
 }
 
 void WebGraphicsContext3DInProcessCommandBufferImpl::SetLock(base::Lock* lock) {
diff --git a/ios/chrome/browser/browser_state/off_the_record_chrome_browser_state_io_data.mm b/ios/chrome/browser/browser_state/off_the_record_chrome_browser_state_io_data.mm
index 8156acd..f507cd4 100644
--- a/ios/chrome/browser/browser_state/off_the_record_chrome_browser_state_io_data.mm
+++ b/ios/chrome/browser/browser_state/off_the_record_chrome_browser_state_io_data.mm
@@ -4,7 +4,7 @@
 
 #include "ios/chrome/browser/browser_state/off_the_record_chrome_browser_state_io_data.h"
 
-#import <UIKit/UIkit.h>
+#import <UIKit/UIKit.h>
 
 #include <utility>
 
diff --git a/media/mojo/common/mojo_shared_buffer_video_frame.h b/media/mojo/common/mojo_shared_buffer_video_frame.h
index 11f96f7..69562c8a 100644
--- a/media/mojo/common/mojo_shared_buffer_video_frame.h
+++ b/media/mojo/common/mojo_shared_buffer_video_frame.h
@@ -82,7 +82,6 @@
   // can be transferred across a mojo connection.
   friend struct mojo::TypeConverter<mojo::StructPtr<interfaces::VideoFrame>,
                                     scoped_refptr<VideoFrame>>;
-  friend class MojoDecryptorService;
 
   MojoSharedBufferVideoFrame(VideoPixelFormat format,
                              const gfx::Size& coded_size,
diff --git a/media/mojo/interfaces/BUILD.gn b/media/mojo/interfaces/BUILD.gn
index 8931fb34..5d336ff3 100644
--- a/media/mojo/interfaces/BUILD.gn
+++ b/media/mojo/interfaces/BUILD.gn
@@ -6,7 +6,6 @@
 
 mojom("interfaces") {
   sources = [
-    "audio_decoder.mojom",
     "content_decryption_module.mojom",
     "decryptor.mojom",
     "demuxer_stream.mojom",
diff --git a/media/mojo/interfaces/audio_decoder.mojom b/media/mojo/interfaces/audio_decoder.mojom
deleted file mode 100644
index c0d2378..0000000
--- a/media/mojo/interfaces/audio_decoder.mojom
+++ /dev/null
@@ -1,43 +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.
-
-module media.interfaces;
-
-import "media/mojo/interfaces/media_types.mojom";
-
-interface AudioDecoder {
-  // Status of a decode operation. See media::AudioDecoder for description.
-  enum DecodeStatus {
-    OK,       // We're all good.
-    ABORTED,  // We aborted as a result of Reset() or destruction.
-    ERROR,    // A decoding error occurred.
-  };
-
-  // Initializes the AudioDecoder with the audio codec configuration and CDM id.
-  // For the unencrypted streams the |cdm_id| is ignored. Executed the callback
-  // with whether the initialization succeeded, and whether the pipeline needs
-  // bitstream conversion.
-  Initialize(AudioDecoderConfig config, int32 cdm_id)
-     => (bool success, bool needs_bitstream_conversion);
-
-  // Sends the |buffer| to the underlying codec. Should be called only after
-  // Initialize() succeeds. The callback with the status is called after the
-  // decoder has accepted corresponding DecoderBuffer, indicating that the
-  // pipeline can send next buffer to decode.
-  // If |buffer| is an EOS buffer then the decoder must be flushed, i.e. all
-  // pending buffers should be processed, the corresponding decoded buffers
-  // should be returned to the proxy, and only then the service should return
-  // DecoderStatus.
-  Decode(DecoderBuffer buffer) => (DecodeStatus status);
-
-  // Resets decoder state. Should be called only if Initialize() succeeds.
-  // All pending Decode() requests will be finished or aborted, then the method
-  // executes the callback.
-  Reset() => ();
-};
-
-interface AudioDecoderClient {
-  // Sends the decoded audio buffer back to the proxy.
-  OnBufferDecoded(AudioBuffer buffer);
-};
diff --git a/media/mojo/interfaces/decryptor.mojom b/media/mojo/interfaces/decryptor.mojom
index 84f16dd..d063e6b 100644
--- a/media/mojo/interfaces/decryptor.mojom
+++ b/media/mojo/interfaces/decryptor.mojom
@@ -51,12 +51,10 @@
   // been successfully initialized.
   // At most one decrypt-and-decode call is allowed at any time for a
   // |stream_type|.
-  // For video, ReleaseSharedBuffer() must be called when the VideoFrame
-  // is shared memory based and the memory is no longer needed.
   DecryptAndDecodeAudio(DecoderBuffer encrypted)
       => (Status status, array<AudioBuffer>? audio_buffers);
-  DecryptAndDecodeVideo(DecoderBuffer encrypted)
-      => (Status status, VideoFrame? video_frame);
+  DecryptAndDecodeVideo(
+      DecoderBuffer encrypted) => (Status status, VideoFrame? video_frame);
 
   // Resets the decoder for |stream_type| to a clean initialized state and
   // cancels any pending decrypt-and-decode operations immediately with ERROR.
@@ -72,7 +70,4 @@
   // After this operation, the decoder is set to an uninitialized state.
   // The decoder can be reinitialized after it is deinitialized.
   DeinitializeDecoder(DemuxerStream.Type stream_type);
-
-  // Releases the shared memory.
-  ReleaseSharedBuffer(handle<shared_buffer> buffer, uint64 buffer_size);
 };
diff --git a/media/mojo/services/mojo_decryptor.cc b/media/mojo/services/mojo_decryptor.cc
index 838f623..38f694e 100644
--- a/media/mojo/services/mojo_decryptor.cc
+++ b/media/mojo/services/mojo_decryptor.cc
@@ -15,7 +15,6 @@
 #include "media/base/decoder_buffer.h"
 #include "media/base/video_frame.h"
 #include "media/mojo/common/media_type_converters.h"
-#include "media/mojo/common/mojo_shared_buffer_video_frame.h"
 #include "media/mojo/interfaces/decryptor.mojom.h"
 #include "mojo/shell/public/cpp/connect.h"
 
@@ -184,27 +183,9 @@
   }
 
   scoped_refptr<VideoFrame> frame(video_frame.To<scoped_refptr<VideoFrame>>());
-
-  // If using shared memory, ensure that ReleaseSharedBuffer() is called when
-  // |frame| is destroyed.
-  if (frame->storage_type() == VideoFrame::STORAGE_MOJO_SHARED_BUFFER) {
-    MojoSharedBufferVideoFrame* mojo_frame =
-        static_cast<MojoSharedBufferVideoFrame*>(frame.get());
-    mojo_frame->SetMojoSharedBufferDoneCB(base::Bind(
-        &MojoDecryptor::ReleaseSharedBuffer, weak_factory_.GetWeakPtr()));
-  }
-
   video_decode_cb.Run(static_cast<Decryptor::Status>(status), frame);
 }
 
-void MojoDecryptor::ReleaseSharedBuffer(mojo::ScopedSharedBufferHandle buffer,
-                                        size_t buffer_size) {
-  DVLOG(1) << __FUNCTION__;
-  DCHECK(thread_checker_.CalledOnValidThread());
-
-  remote_decryptor_->ReleaseSharedBuffer(std::move(buffer), buffer_size);
-}
-
 void MojoDecryptor::CreateDataPipes() {
   // Allocate DataPipe size based on video content. Video can get quite large;
   // at 4K, VP9 delivers packets which are ~1MB in size; so allow for 50%
diff --git a/media/mojo/services/mojo_decryptor.h b/media/mojo/services/mojo_decryptor.h
index b8c0dab7..131c0d0 100644
--- a/media/mojo/services/mojo_decryptor.h
+++ b/media/mojo/services/mojo_decryptor.h
@@ -57,10 +57,6 @@
                       interfaces::Decryptor::Status status,
                       interfaces::VideoFramePtr video_frame);
 
-  // Called when done with a VideoFrame in order to reuse the shared memory.
-  void ReleaseSharedBuffer(mojo::ScopedSharedBufferHandle buffer,
-                           size_t buffer_size);
-
   // To pass DecoderBuffers to and from the MojoDecryptorService, 2 data pipes
   // are required (one each way). At initialization both pipes are created,
   // and then the handles are passed to the MojoDecryptorService.
diff --git a/media/mojo/services/mojo_decryptor_service.cc b/media/mojo/services/mojo_decryptor_service.cc
index 2759a30..07cb1cc 100644
--- a/media/mojo/services/mojo_decryptor_service.cc
+++ b/media/mojo/services/mojo_decryptor_service.cc
@@ -18,7 +18,6 @@
 #include "media/base/video_decoder_config.h"
 #include "media/base/video_frame.h"
 #include "media/mojo/common/media_type_converters.h"
-#include "media/mojo/common/mojo_shared_buffer_video_frame.h"
 #include "media/mojo/interfaces/demuxer_stream.mojom.h"
 
 namespace media {
@@ -113,12 +112,6 @@
       static_cast<media::Decryptor::StreamType>(stream_type));
 }
 
-void MojoDecryptorService::ReleaseSharedBuffer(
-    mojo::ScopedSharedBufferHandle buffer,
-    uint64_t buffer_size) {
-  in_use_video_frames_.erase(buffer.get().value());
-}
-
 void MojoDecryptorService::OnDecryptDone(
     const DecryptCallback& callback,
     media::Decryptor::Status status,
@@ -181,15 +174,6 @@
     return;
   }
 
-  // If |frame| has shared memory that will be passed back, keep a reference
-  // to it until the other side is done with the memory.
-  if (frame->storage_type() == VideoFrame::STORAGE_MOJO_SHARED_BUFFER) {
-    MojoSharedBufferVideoFrame* mojo_frame =
-        static_cast<MojoSharedBufferVideoFrame*>(frame.get());
-    in_use_video_frames_.insert(
-        std::make_pair(mojo_frame->Handle().value(), frame));
-  }
-
   callback.Run(static_cast<Decryptor::Status>(status),
                interfaces::VideoFrame::From(frame));
 }
diff --git a/media/mojo/services/mojo_decryptor_service.h b/media/mojo/services/mojo_decryptor_service.h
index e81bc512..b5bf2ff2 100644
--- a/media/mojo/services/mojo_decryptor_service.h
+++ b/media/mojo/services/mojo_decryptor_service.h
@@ -53,8 +53,6 @@
       const DecryptAndDecodeVideoCallback& callback) final;
   void ResetDecoder(interfaces::DemuxerStream::Type stream_type) final;
   void DeinitializeDecoder(interfaces::DemuxerStream::Type stream_type) final;
-  void ReleaseSharedBuffer(mojo::ScopedSharedBufferHandle buffer,
-                           uint64_t buffer_size) final;
 
  private:
   // Callback executed once Decrypt() is done.
@@ -94,11 +92,6 @@
   scoped_refptr<MediaKeys> cdm_;
   media::Decryptor* decryptor_;
 
-  // Keep a reference to VideoFrames until ReleaseSharedBuffer() is called
-  // to release it.
-  std::unordered_map<MojoHandle, scoped_refptr<VideoFrame>>
-      in_use_video_frames_;
-
   base::WeakPtr<MojoDecryptorService> weak_this_;
   base::WeakPtrFactory<MojoDecryptorService> weak_factory_;
 
diff --git a/net/BUILD.gn b/net/BUILD.gn
index b9310d9..758ef55 100644
--- a/net/BUILD.gn
+++ b/net/BUILD.gn
@@ -574,23 +574,25 @@
   ]
 }
 
-executable("dump_cache") {
-  testonly = true
-  sources = [
-    "tools/dump_cache/dump_cache.cc",
-    "tools/dump_cache/dump_files.cc",
-    "tools/dump_cache/dump_files.h",
-  ]
+if (!is_ios) {
+  executable("dump_cache") {
+    testonly = true
+    sources = [
+      "tools/dump_cache/dump_cache.cc",
+      "tools/dump_cache/dump_files.cc",
+      "tools/dump_cache/dump_files.h",
+    ]
 
-  # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
-  configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
+    # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
+    configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
 
-  deps = [
-    ":net",
-    ":test_support",
-    "//base",
-    "//build/config/sanitizers:deps",
-  ]
+    deps = [
+      ":net",
+      ":test_support",
+      "//base",
+      "//build/config/sanitizers:deps",
+    ]
+  }
 }
 
 source_set("test_support") {
@@ -1707,40 +1709,43 @@
 }
 
 # !is_android && !is_win && !is_mac
+if (!is_ios) {
+  # TODO(crbug.com/594965): this should be converted to "app" template and
+  # enabled on iOS too.
+  executable("net_perftests") {
+    testonly = true
+    sources = [
+      "base/mime_sniffer_perftest.cc",
+      "cookies/cookie_monster_perftest.cc",
+      "disk_cache/blockfile/disk_cache_perftest.cc",
+      "extras/sqlite/sqlite_persistent_cookie_store_perftest.cc",
+      "proxy/proxy_resolver_perftest.cc",
+      "udp/udp_socket_perftest.cc",
+    ]
 
-executable("net_perftests") {
-  testonly = true
-  sources = [
-    "base/mime_sniffer_perftest.cc",
-    "cookies/cookie_monster_perftest.cc",
-    "disk_cache/blockfile/disk_cache_perftest.cc",
-    "extras/sqlite/sqlite_persistent_cookie_store_perftest.cc",
-    "proxy/proxy_resolver_perftest.cc",
-    "udp/udp_socket_perftest.cc",
-  ]
+    # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
+    configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
+    deps = [
+      ":extras",
+      ":net",
+      ":test_support",
+      "//base",
+      "//base:i18n",
+      "//base/test:test_support_perf",
+      "//build/config/sanitizers:deps",
+      "//testing/gtest",
+      "//url",
+    ]
 
-  # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
-  configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
-  deps = [
-    ":extras",
-    ":net",
-    ":test_support",
-    "//base",
-    "//base:i18n",
-    "//base/test:test_support_perf",
-    "//build/config/sanitizers:deps",
-    "//testing/gtest",
-    "//url",
-  ]
+    if (enable_websockets) {
+      sources += [ "websockets/websocket_frame_perftest.cc" ]
+    }
 
-  if (enable_websockets) {
-    sources += [ "websockets/websocket_frame_perftest.cc" ]
-  }
-
-  if (use_v8_in_net) {
-    deps += [ ":net_with_v8" ]
-  } else {
-    sources -= [ "proxy/proxy_resolver_perftest.cc" ]
+    if (use_v8_in_net) {
+      deps += [ ":net_with_v8" ]
+    } else {
+      sources -= [ "proxy/proxy_resolver_perftest.cc" ]
+    }
   }
 }
 
diff --git a/skia/config/SkUserConfig.h b/skia/config/SkUserConfig.h
index 727ace6..1ea18f8 100644
--- a/skia/config/SkUserConfig.h
+++ b/skia/config/SkUserConfig.h
@@ -247,6 +247,10 @@
 #   define SK_SUPPORT_LEGACY_CREATESHADER_PTR
 #endif
 
+#ifndef    SK_SUPPORT_LEGACY_SETSHADER_PTR
+#   define SK_SUPPORT_LEGACY_SETSHADER_PTR
+#endif
+
 ///////////////////////// Imported from BUILD.gn and skia_common.gypi
 
 /* In some places Skia can use static initializers for global initialization,
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json
index 5788b63cf2..928e9b864 100644
--- a/testing/buildbot/chromium.gpu.fyi.json
+++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -1259,6 +1259,426 @@
       }
     ]
   },
+  "Linux Release (NVIDIA GeForce 730)": {
+    "gtest_tests": [
+      {
+        "args": [
+          "--use-gpu-in-tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0f02",
+              "os": "Linux"
+            }
+          ]
+        },
+        "test": "angle_end2end_tests",
+        "use_xvfb": false
+      },
+      {
+        "args": [
+          "--use-gpu-in-tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0f02",
+              "os": "Linux"
+            }
+          ]
+        },
+        "test": "angle_unittests",
+        "use_xvfb": false
+      },
+      {
+        "args": [
+          "--use-gpu-in-tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0f02",
+              "os": "Linux"
+            }
+          ]
+        },
+        "test": "audio_unittests",
+        "use_xvfb": false
+      },
+      {
+        "args": [
+          "--enable-gpu",
+          "--test-launcher-jobs=1",
+          "--gtest_filter=CastStreamingApiTestWithPixelOutput.EndToEnd*:TabCaptureApiPixelTest.EndToEnd*"
+        ],
+        "name": "tab_capture_end2end_tests",
+        "test": "browser_tests",
+        "use_xvfb": false
+      },
+      {
+        "args": [
+          "--use-gpu-in-tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0f02",
+              "os": "Linux"
+            }
+          ]
+        },
+        "test": "content_gl_tests",
+        "use_xvfb": false
+      },
+      {
+        "args": [
+          "--use-gpu-in-tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0f02",
+              "os": "Linux"
+            }
+          ]
+        },
+        "test": "gl_tests",
+        "use_xvfb": false
+      },
+      {
+        "args": [
+          "--use-gpu-in-tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0f02",
+              "os": "Linux"
+            }
+          ]
+        },
+        "test": "gl_unittests",
+        "use_xvfb": false
+      },
+      {
+        "args": [
+          "--use-gpu-in-tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0f02",
+              "os": "Linux"
+            }
+          ]
+        },
+        "test": "gles2_conform_test",
+        "use_xvfb": false
+      }
+    ],
+    "isolated_scripts": [
+      {
+        "args": [
+          "context_lost",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_test",
+        "name": "context_lost_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0f02",
+              "os": "Linux"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "gpu_process",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_test",
+        "name": "gpu_process_launch_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0f02",
+              "os": "Linux"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "gpu_rasterization",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_test",
+        "name": "gpu_rasterization_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0f02",
+              "os": "Linux"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "hardware_accelerated_feature",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_test",
+        "name": "hardware_accelerated_feature_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0f02",
+              "os": "Linux"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "maps",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_test",
+        "name": "maps_pixel_test",
+        "override_compile_targets": [
+          "telemetry_gpu_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0f02",
+              "os": "Linux"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "memory_test",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_test",
+        "name": "memory_test",
+        "override_compile_targets": [
+          "telemetry_gpu_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0f02",
+              "os": "Linux"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "pixel",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
+          "--refimg-cloud-storage-bucket",
+          "chromium-gpu-archive/reference-images",
+          "--os-type",
+          "linux",
+          "--build-revision",
+          "${got_revision}",
+          "--test-machine-name",
+          "${buildername}"
+        ],
+        "isolate_name": "telemetry_gpu_test",
+        "name": "pixel_test",
+        "non_precommit_args": [
+          "--upload-refimg-to-cloud-storage"
+        ],
+        "override_compile_targets": [
+          "telemetry_gpu_test_run"
+        ],
+        "precommit_args": [
+          "--download-refimg-from-cloud-storage"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0f02",
+              "os": "Linux"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "screenshot_sync",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_test",
+        "name": "screenshot_sync_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0f02",
+              "os": "Linux"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "trace_test",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_test",
+        "name": "trace_test",
+        "override_compile_targets": [
+          "telemetry_gpu_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0f02",
+              "os": "Linux"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "webgl_conformance",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
+          "--webgl-conformance-version=2.0.0",
+          "--webgl2-only=true"
+        ],
+        "isolate_name": "telemetry_gpu_test",
+        "name": "webgl2_conformance_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0f02",
+              "os": "Linux"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "webgl_conformance",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-gl=angle"
+        ],
+        "isolate_name": "telemetry_gpu_test",
+        "name": "webgl_conformance_angle_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0f02",
+              "os": "Linux"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "webgl_conformance",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_test",
+        "name": "webgl_conformance_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0f02",
+              "os": "Linux"
+            }
+          ]
+        }
+      }
+    ]
+  },
   "Linux Release (NVIDIA)": {
     "gtest_tests": [
       {
@@ -7174,6 +7594,486 @@
       }
     ]
   },
+  "Win7 Release (NVIDIA GeForce 730)": {
+    "gtest_tests": [
+      {
+        "args": [
+          "--use-gpu-in-tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0f02",
+              "os": "Windows-2008ServerR2-SP1"
+            }
+          ]
+        },
+        "test": "angle_end2end_tests",
+        "use_xvfb": false
+      },
+      {
+        "args": [
+          "--use-gpu-in-tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0f02",
+              "os": "Windows-2008ServerR2-SP1"
+            }
+          ]
+        },
+        "test": "angle_unittests",
+        "use_xvfb": false
+      },
+      {
+        "args": [
+          "--use-gpu-in-tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0f02",
+              "os": "Windows-2008ServerR2-SP1"
+            }
+          ]
+        },
+        "test": "audio_unittests",
+        "use_xvfb": false
+      },
+      {
+        "args": [
+          "--enable-gpu",
+          "--test-launcher-jobs=1",
+          "--gtest_filter=CastStreamingApiTestWithPixelOutput.EndToEnd*:TabCaptureApiPixelTest.EndToEnd*"
+        ],
+        "name": "tab_capture_end2end_tests",
+        "test": "browser_tests",
+        "use_xvfb": false
+      },
+      {
+        "args": [
+          "--use-gpu-in-tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0f02",
+              "os": "Windows-2008ServerR2-SP1"
+            }
+          ]
+        },
+        "test": "content_gl_tests",
+        "use_xvfb": false
+      },
+      {
+        "args": [
+          "--use-gpu-in-tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0f02",
+              "os": "Windows-2008ServerR2-SP1"
+            }
+          ]
+        },
+        "test": "gl_tests",
+        "use_xvfb": false
+      },
+      {
+        "args": [
+          "--use-gpu-in-tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0f02",
+              "os": "Windows-2008ServerR2-SP1"
+            }
+          ]
+        },
+        "test": "gl_unittests",
+        "use_xvfb": false
+      },
+      {
+        "args": [
+          "--use-gpu-in-tests",
+          "--use-angle=d3d9"
+        ],
+        "name": "gles2_conform_d3d9_test",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0f02",
+              "os": "Windows-2008ServerR2-SP1"
+            }
+          ]
+        },
+        "test": "gles2_conform_test",
+        "use_xvfb": false
+      },
+      {
+        "args": [
+          "--use-gpu-in-tests",
+          "--use-angle=gl",
+          "--disable-gpu-sandbox"
+        ],
+        "name": "gles2_conform_gl_test",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0f02",
+              "os": "Windows-2008ServerR2-SP1"
+            }
+          ]
+        },
+        "test": "gles2_conform_test",
+        "use_xvfb": false
+      },
+      {
+        "args": [
+          "--use-gpu-in-tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0f02",
+              "os": "Windows-2008ServerR2-SP1"
+            }
+          ]
+        },
+        "test": "gles2_conform_test",
+        "use_xvfb": false
+      }
+    ],
+    "isolated_scripts": [
+      {
+        "args": [
+          "context_lost",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_test",
+        "name": "context_lost_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0f02",
+              "os": "Windows-2008ServerR2-SP1"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "gpu_process",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_test",
+        "name": "gpu_process_launch_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0f02",
+              "os": "Windows-2008ServerR2-SP1"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "gpu_rasterization",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_test",
+        "name": "gpu_rasterization_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0f02",
+              "os": "Windows-2008ServerR2-SP1"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "hardware_accelerated_feature",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_test",
+        "name": "hardware_accelerated_feature_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0f02",
+              "os": "Windows-2008ServerR2-SP1"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "maps",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_test",
+        "name": "maps_pixel_test",
+        "override_compile_targets": [
+          "telemetry_gpu_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0f02",
+              "os": "Windows-2008ServerR2-SP1"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "memory_test",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_test",
+        "name": "memory_test",
+        "override_compile_targets": [
+          "telemetry_gpu_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0f02",
+              "os": "Windows-2008ServerR2-SP1"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "pixel",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
+          "--refimg-cloud-storage-bucket",
+          "chromium-gpu-archive/reference-images",
+          "--os-type",
+          "win",
+          "--build-revision",
+          "${got_revision}",
+          "--test-machine-name",
+          "${buildername}"
+        ],
+        "isolate_name": "telemetry_gpu_test",
+        "name": "pixel_test",
+        "non_precommit_args": [
+          "--upload-refimg-to-cloud-storage"
+        ],
+        "override_compile_targets": [
+          "telemetry_gpu_test_run"
+        ],
+        "precommit_args": [
+          "--download-refimg-from-cloud-storage"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0f02",
+              "os": "Windows-2008ServerR2-SP1"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "screenshot_sync",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_test",
+        "name": "screenshot_sync_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0f02",
+              "os": "Windows-2008ServerR2-SP1"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "trace_test",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_test",
+        "name": "trace_test",
+        "override_compile_targets": [
+          "telemetry_gpu_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0f02",
+              "os": "Windows-2008ServerR2-SP1"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "webgl_conformance",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
+          "--webgl-conformance-version=2.0.0",
+          "--webgl2-only=true"
+        ],
+        "isolate_name": "telemetry_gpu_test",
+        "name": "webgl2_conformance_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0f02",
+              "os": "Windows-2008ServerR2-SP1"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "webgl_conformance",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-angle=d3d9"
+        ],
+        "isolate_name": "telemetry_gpu_test",
+        "name": "webgl_conformance_d3d9_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0f02",
+              "os": "Windows-2008ServerR2-SP1"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "webgl_conformance",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-angle=gl"
+        ],
+        "isolate_name": "telemetry_gpu_test",
+        "name": "webgl_conformance_gl_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0f02",
+              "os": "Windows-2008ServerR2-SP1"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "webgl_conformance",
+          "--show-stdout",
+          "--browser=release",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_test",
+        "name": "webgl_conformance_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0f02",
+              "os": "Windows-2008ServerR2-SP1"
+            }
+          ]
+        }
+      }
+    ]
+  },
   "Win7 Release (NVIDIA)": {
     "gtest_tests": [
       {
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index eca6e81..9ef239e6 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -1347,8 +1347,6 @@
 crbug.com/594672 virtual/trustedeventsdefaultaction/fast/events/scale-and-scroll-iframe-body.html [ Failure Pass ]
 crbug.com/594672 virtual/trustedeventsdefaultaction/fast/events/updateLayoutForHitTest.html [ Failure Pass ]
 
-crbug.com/589525 svg/text/combining-character-queries.html [ NeedsRebaseline ]
-
 crbug.com/593888 [ Linux Debug ] fast/dom/htmlcollection-reachable.html [ Timeout ]
 
 crbug.com/593568 [ Win Debug ] virtual/threaded/fast/scroll-behavior/smooth-scroll/horizontal-smooth-scroll-in-rtl.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/css3/flexbox/definite-cross-sizes.html b/third_party/WebKit/LayoutTests/css3/flexbox/definite-cross-sizes.html
index f6f2a165..d78de16a 100644
--- a/third_party/WebKit/LayoutTests/css3/flexbox/definite-cross-sizes.html
+++ b/third_party/WebKit/LayoutTests/css3/flexbox/definite-cross-sizes.html
@@ -81,11 +81,11 @@
   </div>
 </div>
 
-<p>Tests that we get an definite size in a nested flexbox where only the outer one has an explicit height and has an opposite direction. TODO: This is currently considered indefinite pending crbug.com/346275</p>
+<p>Tests that we get an definite size in a nested flexbox where only the outer one has an explicit height and has an opposite direction.</p>
 <div class="flexbox" style="height: 50px;" data-expected-height="50">
-  <div class="flexbox column flex-one" data-expected-height="50">
-    <div data-expected-height="50">
-      <div style="height: 50%" data-expected-height="50"> <!-- TODO: should be 25 pending the above bug -->
+  <div class="flexbox column" data-expected-height="50">
+    <div class="flex-one" data-expected-height="50">
+      <div style="height: 50%" data-expected-height="25">
         <div class="rect" data-expected-height="50"></div>
       </div>
     </div>
diff --git a/third_party/WebKit/LayoutTests/css3/flexbox/definite-main-size.html b/third_party/WebKit/LayoutTests/css3/flexbox/definite-main-size.html
new file mode 100644
index 0000000..4827a28
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/css3/flexbox/definite-main-size.html
@@ -0,0 +1,72 @@
+<!DOCTYPE html>
+
+<title>CSS Flexbox: Definite main sizes</title>
+
+<style>
+.rect {
+  width: 50px;
+  height: 50px;
+  background-color: green;
+}
+
+.flexbox {
+  border: 3px solid black;
+}
+
+.flexbox > div > div {
+  overflow: hidden;
+}
+
+</style>
+
+<link rel="stylesheet" href="resources/flexbox.css">
+<link rel="help" href="https://drafts.csswg.org/css-flexbox/#definite-sizes">
+<link rel="author" title="Google Inc." href="https://www.google.com/">
+
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script src="../../resources/check-layout-th.js"></script>
+
+<body onload="checkLayout('.flexbox')" style="height: 800px;">
+<div id=log></div>
+
+<p>Simple case of percentage resolution:</p>
+<div class="flexbox" style="width: 300px;">
+  <div class="flex-one" data-expected-width="250">
+    <div style="width: 50%;" data-expected-width="125">
+      <div class="rect"></div>
+    </div>
+  </div>
+  <div class="rect flex-none"></div>
+</div>
+
+<p>auto flex-basis. However, as this is a width, we follow regular width
+rules and resolve the percentage:</p>
+<div class="flexbox" style="width: 300px;">
+  <div data-expected-width="50">
+    <div style="width: 50%;" data-expected-width="25">
+      <div class="rect"></div>
+    </div>
+  </div>
+  <div class="rect flex-none"></div>
+</div>
+
+<p>Simple case of percentage resolution, columns:</p>
+<div class="flexbox column" style="height: 300px;">
+  <div class="flex-one" data-expected-height="250">
+    <div style="height: 50%;" data-expected-height="125">
+      <div class="rect"></div>
+    </div>
+  </div>
+  <div class="rect flex-none"></div>
+</div>
+
+<p>auto flex-basis, we should ignore the percentage height here:</p>
+<div class="flexbox column" style="height: 300px;">
+  <div data-expected-height="50">
+    <div style="height: 50%;" data-expected-height="50">
+      <div class="rect"></div>
+    </div>
+  </div>
+  <div class="rect flex-none"></div>
+</div>
diff --git a/third_party/WebKit/LayoutTests/css3/flexbox/flex-flow-padding.html b/third_party/WebKit/LayoutTests/css3/flexbox/flex-flow-padding.html
index 7c3fd5f4..bf0119c 100644
--- a/third_party/WebKit/LayoutTests/css3/flexbox/flex-flow-padding.html
+++ b/third_party/WebKit/LayoutTests/css3/flexbox/flex-flow-padding.html
@@ -94,14 +94,14 @@
             containersize: horizontalContainerSize,
             flexitemcolumn: [30, 100, 110, 10],
             flexitemrow: [100, 50, 40, 10],
-            childcolumn: [20, 20, 118, 23],
+            childcolumn: [20, 70, 118, 23],
             childrow: [90, 20, 48, 23]
         },
         ltr : {
             containersize: horizontalContainerSize,
             flexitemcolumn: [30, 100, 40, 10],
             flexitemrow: [100, 50, 40, 10],
-            childcolumn: [20, 20, 48, 23],
+            childcolumn: [20, 70, 48, 23],
             childrow: [90, 20, 48, 23]
         }
     },
@@ -110,14 +110,14 @@
             containersize: horizontalContainerSize,
             flexitemcolumn: [100, 50, 40, 60],
             flexitemrow: [30, 100, 40, 10],
-            childcolumn: [20, 20, 48, 73],
+            childcolumn: [90, 20, 48, 73],
             childrow: [20, 70, 48, 23]
         },
         ltr : {
             containersize: horizontalContainerSize,
             flexitemcolumn: [100, 50, 40, 10],
             flexitemrow: [30, 100, 40, 10],
-            childcolumn: [20, 20, 48, 23],
+            childcolumn: [90, 20, 48, 23],
             childrow: [20, 70, 48, 23]
         }
     },
@@ -126,14 +126,14 @@
             containersize: horizontalContainerSize,
             flexitemcolumn: [100, 50, 40, 60],
             flexitemrow: [30, 100, 110, 10],
-            childcolumn: [20, 20, 118, 73],
+            childcolumn: [90, 20, 48, 73],
             childrow: [20, 70, 118, 23]
         },
         ltr : {
             containersize: horizontalContainerSize,
             flexitemcolumn: [100, 50, 40, 10],
             flexitemrow: [30, 100, 110, 10],
-            childcolumn: [20, 20, 118, 23],
+            childcolumn: [90, 20, 48, 23],
             childrow: [20, 70, 118, 23]
         }
     }
@@ -145,14 +145,14 @@
             containersize: horizontalContainerSize,
             flexitemcolumn: [30, 100, 90, 10],
             flexitemrow: [100, 50, 20, 10],
-            childcolumn: [20, 20, 92, 23],
+            childcolumn: [20, 70, 92, 23],
             childrow: [90, 20, 22, 23]
         },
         ltr : {
             containersize: horizontalContainerSize,
             flexitemcolumn: [30, 100, 40, 10],
             flexitemrow: [100, 50, 40, 10],
-            childcolumn: [20, 20, 48, 23],
+            childcolumn: [20, 70, 48, 23],
             childrow: [90, 20, 48, 23]
         }
     },
@@ -161,14 +161,14 @@
             containersize: verticalContainerSize,
             flexitemcolumn: [100, 30, 10, 90],
             flexitemrow: [50, 100, 10, 20],
-            childcolumn: [20, 20, 23, 92],
+            childcolumn: [70, 20, 23, 92],
             childrow: [20, 90, 23, 22]
         },
         ltr : {
             containersize: verticalContainerSize,
             flexitemcolumn: [100, 30, 10, 40],
             flexitemrow: [50, 100, 10, 40],
-            childcolumn: [20, 20, 23, 48],
+            childcolumn: [70, 20, 23, 48],
             childrow: [20, 90, 23, 48]
         }
     },
@@ -177,14 +177,14 @@
             containersize: verticalContainerSize,
             flexitemcolumn: [100, 30, 30, 90],
             flexitemrow: [50, 100, 80, 20],
-            childcolumn: [20, 20, 97, 92],
+            childcolumn: [70, 20, 47, 92],
             childrow: [20, 90, 97, 22]
         },
         ltr : {
             containersize: verticalContainerSize,
             flexitemcolumn: [100, 30, 30, 40],
             flexitemrow: [50, 100, 80, 40],
-            childcolumn: [20, 20, 97, 48],
+            childcolumn: [70, 20, 47, 48],
             childrow: [20, 90, 97, 48]
         }
     }
diff --git a/third_party/WebKit/LayoutTests/editing/execCommand/enabling-and-selection-expected.txt b/third_party/WebKit/LayoutTests/editing/execCommand/enabling-and-selection-expected.txt
index 4bb14071..b25473d4 100644
--- a/third_party/WebKit/LayoutTests/editing/execCommand/enabling-and-selection-expected.txt
+++ b/third_party/WebKit/LayoutTests/editing/execCommand/enabling-and-selection-expected.txt
@@ -11,9 +11,9 @@
 PASS whenEnabled('Cut') is 'editable range'
 PASS whenEnabled('RemoveFormat') is 'editable range'
 PASS whenEnabled('Delete') is 'editable'
-PASS whenEnabled('FontName') is 'editable'
-PASS whenEnabled('FontSize') is 'editable'
-PASS whenEnabled('FontSizeDelta') is 'editable'
+PASS whenEnabled('FontName') is 'richly editable'
+PASS whenEnabled('FontSize') is 'richly editable'
+PASS whenEnabled('FontSizeDelta') is 'richly editable'
 PASS whenEnabled('ForwardDelete') is 'editable'
 PASS whenEnabled('InsertHTML') is 'editable'
 PASS whenEnabled('InsertParagraph') is 'editable'
diff --git a/third_party/WebKit/LayoutTests/editing/execCommand/script-tests/enabling-and-selection.js b/third_party/WebKit/LayoutTests/editing/execCommand/script-tests/enabling-and-selection.js
index 4b1c516e..43e6460 100644
--- a/third_party/WebKit/LayoutTests/editing/execCommand/script-tests/enabling-and-selection.js
+++ b/third_party/WebKit/LayoutTests/editing/execCommand/script-tests/enabling-and-selection.js
@@ -85,9 +85,9 @@
 shouldBe("whenEnabled('RemoveFormat')", "'editable range'");
 
 shouldBe("whenEnabled('Delete')", "'editable'");
-shouldBe("whenEnabled('FontName')", "'editable'");
-shouldBe("whenEnabled('FontSize')", "'editable'");
-shouldBe("whenEnabled('FontSizeDelta')", "'editable'");
+shouldBe("whenEnabled('FontName')", "'richly editable'");
+shouldBe("whenEnabled('FontSize')", "'richly editable'");
+shouldBe("whenEnabled('FontSizeDelta')", "'richly editable'");
 shouldBe("whenEnabled('ForwardDelete')", "'editable'");
 shouldBe("whenEnabled('InsertHTML')", "'editable'");
 shouldBe("whenEnabled('InsertParagraph')", "'editable'");
diff --git a/third_party/WebKit/LayoutTests/fast/forms/plaintext-mode-1-expected.txt b/third_party/WebKit/LayoutTests/fast/forms/plaintext-mode-1-expected.txt
index 85d528e..0a78d2b0 100644
--- a/third_party/WebKit/LayoutTests/fast/forms/plaintext-mode-1-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/forms/plaintext-mode-1-expected.txt
@@ -5,9 +5,9 @@
 Success: document.queryCommandEnabled("CreateLink") == false
 Success: document.queryCommandEnabled("Cut") == true
 Success: document.queryCommandEnabled("Delete") == true
-Success: document.queryCommandEnabled("FontName") == true
-Success: document.queryCommandEnabled("FontSize") == true
-Success: document.queryCommandEnabled("FontSizeDelta") == true
+Success: document.queryCommandEnabled("FontName") == false
+Success: document.queryCommandEnabled("FontSize") == false
+Success: document.queryCommandEnabled("FontSizeDelta") == false
 Success: document.queryCommandEnabled("ForeColor") == false
 Success: document.queryCommandEnabled("ForwardDelete") == true
 Success: document.queryCommandEnabled("Indent") == false
diff --git a/third_party/WebKit/LayoutTests/fast/forms/plaintext-mode-1.html b/third_party/WebKit/LayoutTests/fast/forms/plaintext-mode-1.html
index 4f9851f9..82ecc4f 100644
--- a/third_party/WebKit/LayoutTests/fast/forms/plaintext-mode-1.html
+++ b/third_party/WebKit/LayoutTests/fast/forms/plaintext-mode-1.html
@@ -38,9 +38,9 @@
 assert("document.queryCommandEnabled", "CreateLink", false);
 assert("document.queryCommandEnabled", "Cut", true);
 assert("document.queryCommandEnabled", "Delete", true);
-assert("document.queryCommandEnabled", "FontName", true); // Shouldn't this be false?
-assert("document.queryCommandEnabled", "FontSize", true); // Shouldn't this be false?
-assert("document.queryCommandEnabled", "FontSizeDelta", true); // Shouldn't this be false?
+assert("document.queryCommandEnabled", "FontName", false);
+assert("document.queryCommandEnabled", "FontSize", false);
+assert("document.queryCommandEnabled", "FontSizeDelta", false);
 assert("document.queryCommandEnabled", "ForeColor", false);
 assert("document.queryCommandEnabled", "ForwardDelete", true);
 assert("document.queryCommandEnabled", "Indent", false);
diff --git a/third_party/WebKit/LayoutTests/fast/overflow/resources/transformed-frame-scrolledIntoView-frame.html b/third_party/WebKit/LayoutTests/fast/overflow/resources/transformed-frame-scrolledIntoView-frame.html
new file mode 100644
index 0000000..a5e6076
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/overflow/resources/transformed-frame-scrolledIntoView-frame.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<style>
+::-webkit-scrollbar {
+    width: 0;
+    height: 0;
+}
+
+#green {
+    position: absolute;
+    left: 0;
+    top: 150px;
+    width: 100px;
+    height: 100px;
+    background: green;
+}
+
+#bloat {
+    height: 1000px;
+}
+</style>
+<div id="green"></div>
+<div id="bloat"></div>
diff --git a/third_party/WebKit/LayoutTests/fast/overflow/transformed-frame-scrollIntoView-expected.png b/third_party/WebKit/LayoutTests/fast/overflow/transformed-frame-scrollIntoView-expected.png
new file mode 100644
index 0000000..575ffd03
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/overflow/transformed-frame-scrollIntoView-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/overflow/transformed-frame-scrollIntoView-expected.txt b/third_party/WebKit/LayoutTests/fast/overflow/transformed-frame-scrollIntoView-expected.txt
new file mode 100644
index 0000000..f818729
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/overflow/transformed-frame-scrollIntoView-expected.txt
@@ -0,0 +1,18 @@
+layer at (0,0) size 800x600 scrollY 200.00 scrollHeight 2016
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x2016 backgroundClip at (0,0) size 800x600 clip at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x2016
+    LayoutBlockFlow {BODY} at (8,8) size 784x2000
+      LayoutBlockFlow {DIV} at (0,0) size 784x2000
+layer at (0,400) size 300x200
+  LayoutIFrame (positioned) {IFRAME} at (0,400) size 300x200
+    layer at (0,0) size 300x200 scrollY 50.00 scrollHeight 1016
+      LayoutView at (0,0) size 300x200
+    layer at (0,0) size 300x1016 backgroundClip at (0,0) size 300x200 clip at (0,0) size 300x200
+      LayoutBlockFlow {HTML} at (0,0) size 300x1016
+        LayoutBlockFlow {BODY} at (8,8) size 284x1000
+          LayoutBlockFlow {DIV} at (0,0) size 284x1000
+    layer at (0,150) size 100x100 backgroundClip at (0,0) size 300x200 clip at (0,0) size 300x200
+      LayoutBlockFlow (positioned) {DIV} at (0,150) size 100x100 [bgcolor=#008000]
+scrolled to 0,200
+frame '<!--framePath //<!--frame0-->-->' scrolled to 0,50
diff --git a/third_party/WebKit/LayoutTests/fast/overflow/transformed-frame-scrollIntoView.html b/third_party/WebKit/LayoutTests/fast/overflow/transformed-frame-scrollIntoView.html
new file mode 100644
index 0000000..8cb7b15
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/overflow/transformed-frame-scrollIntoView.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<style>
+::-webkit-scrollbar {
+    width: 0;
+    height: 0;
+}
+
+#frame {
+    position: absolute;
+    left: 0;
+    top: 400px;
+    width: 300px;
+    height: 200px;
+    border: 0;
+    transform-origin: 0 0;
+    transform: scale(2);
+}
+
+#bloat {
+    height: 2000px
+}
+</style>
+<iframe id="frame" src="resources/transformed-frame-scrolledIntoView-frame.html"></iframe>
+<div id="bloat">
+</div>
+<script>
+if (window.testRunner) {
+    testRunner.waitUntilDone();
+    testRunner.dumpChildFrameScrollPositions();
+}
+document.getElementById('frame').contentWindow.addEventListener('load', function() {
+    document.getElementById('frame').contentDocument.getElementById('green').scrollIntoViewIfNeeded(false);
+    if (window.testRunner)
+        testRunner.notifyDone();
+});
+</script>
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/debugger/debugger-setVariableValue-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/debugger/debugger-setVariableValue-expected.txt
deleted file mode 100644
index 633edf35..0000000
--- a/third_party/WebKit/LayoutTests/inspector-protocol/debugger/debugger-setVariableValue-expected.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-Closure returns: {"type":"string","value":"ttttrue52013"}
- (expected: 'ttttrue52013')
-Debugger.setVariableValue OK
-Closure returns: {"type":"string","value":"ttttrue42013"}
- (expected: 'ttttrue42013')
-Expected error: {"code":-32000,"message":"Either call frame or function object must be specified"}
-Expected error
-Expected error
-
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/debugger/debugger-setVariableValue.html b/third_party/WebKit/LayoutTests/inspector-protocol/debugger/debugger-setVariableValue.html
deleted file mode 100644
index f4d9e23..0000000
--- a/third_party/WebKit/LayoutTests/inspector-protocol/debugger/debugger-setVariableValue.html
+++ /dev/null
@@ -1,181 +0,0 @@
-<html>
-<head>
-<script type="text/javascript" src="../../http/tests/inspector-protocol/inspector-protocol-test.js"></script>
-<script>
-
-function test()
-{
-    // A general-purpose engine for sending a sequence of protocol commands.
-    // The clients provide requests and response handlers, while the engine catches
-    // errors and makes sure that once there's nothing to do completeTest() is called.
-    // @param step is an object with command, params and callback fields 
-    function runRequestSeries(step) {
-        processStep(step);
-
-        function processStep(s) {
-            try {
-                processStepOrFail(s);
-            } catch (e) {
-                InspectorTest.log(e.stack);
-                InspectorTest.completeTest();
-            }
-        }
-        
-        function processStepOrFail(s) {
-            if (!s) {
-                InspectorTest.completeTest();
-                return;
-            }
-            if (!s.command) {
-                // A simple loopback step.
-                var next = s.callback();
-                processStep(next);
-                return;
-            }
-
-            var innerCallback = function(response) {
-                var next;
-                if ("error" in response) {
-                    if (!("errorHandler" in s)) {
-                        // Error message is not logged intentionally, it may be platform-specific.
-                        InspectorTest.log("Protocol command '" + s.command + "' failed");
-                        InspectorTest.completeTest();
-                        return;
-                    }
-                    try {
-                        next = s.errorHandler(response.error);
-                    } catch (e) {
-                        InspectorTest.log(e.stack);
-                        InspectorTest.completeTest();
-                        return;
-                    }
-                } else {
-                    try {
-                        next = s.callback(response.result);
-                    } catch (e) {
-                        InspectorTest.log(e.stack);
-                        InspectorTest.completeTest();
-                        return;
-                    }
-                }
-                processStep(next);
-            }
-            InspectorTest.sendCommand(s.command, s.params, innerCallback);
-        }
-    }
-    
-    var firstStep = { callback: enableDebugger };
-
-    runRequestSeries(firstStep);
-    
-    function enableDebugger() {
-        return { command: "Debugger.enable", params: {}, callback: evalFunction };
-    }
-    
-    // Testing function/closure scopes.
-    
-    function evalFunction(response) {
-        var expression = "(function(p){var r=5;with({year:2013}){return function Closure(q){return p+q+r+year};}})('ttt')";
-        return { command: "Runtime.evaluate", params: {expression: expression}, callback: callbackEvalFunction };
-    }
-    
-    function callbackEvalFunction(result) {
-        var id = result.result.objectId;
-        if (id === undefined)
-            throw new Error("objectId is expected");
-        return createCheckFunctionStepChain(id);
-    }
-
-    function createCheckFunctionStepChain(functionObjectId) {
-        var params = {
-            objectId: functionObjectId,
-            functionDeclaration: "function(){return this(true);}"
-        };
-        return {
-            command: "Runtime.callFunctionOn", params: params, callback: callbackLogClosureEval
-        };
-
-	    function callbackLogClosureEval(result) {
-	        InspectorTest.log("Closure returns: " + JSON.stringify(result.result));
-	        InspectorTest.log(" (expected: 'ttttrue52013')");
-	        
-	        var params = {
-	            functionObjectId: functionObjectId,
-	            scopeNumber: 1,
-	            variableName: "r",
-	            newValue: { value: 4 }
-	        };
-	        return {
-	            command: "Debugger.setVariableValue", params: params, callback: setVariableCallback
-	        };
-	    }
-	    
-	    function setVariableCallback() {
-	        InspectorTest.log("Debugger.setVariableValue OK");
-	        
-	        var params = {
-	            objectId: functionObjectId,
-	            functionDeclaration: "function(){return this(true);}"
-	        };
-	        return {
-	            command: "Runtime.callFunctionOn", params: params, callback: callbackLogClosureEval2
-	        };
-	        
-	    }
-
-	    function callbackLogClosureEval2(result) {
-	        InspectorTest.log("Closure returns: " + JSON.stringify(result.result));
-	        InspectorTest.log(" (expected: 'ttttrue42013')");
-	        
-	        var params = {
-	            // No target is specified
-	            scopeNumber: 1,
-	            variableName: "r",
-	            newValue: { value: 4 }
-	        };
-	        return {
-	            command: "Debugger.setVariableValue", params: params, errorHandler: setVariableErrorCallback3
-	        };
-	    }
-	    
-	    function setVariableErrorCallback3(error) {
-	        InspectorTest.log("Expected error: " + JSON.stringify(error));
-
-	        var params = {
-	            functionObjectId: functionObjectId,
-	            scopeNumber: 100, // Wrong scope number
-	            variableName: "r",
-	            newValue: { value: 4 }
-	        };
-	        return {
-	            command: "Debugger.setVariableValue", params: params, errorHandler: setVariableErrorCallback4
-	        };
-	    }
-	    
-	    function setVariableErrorCallback4(error) {
-	        InspectorTest.log("Expected error");
-
-	        var params = {
-	            functionObjectId: functionObjectId,
-	            scopeNumber: 1,
-	            variableName: "bad", // Wrong variable name
-	            newValue: { value: 4 }
-	        };
-	        return {
-	            command: "Debugger.setVariableValue", params: params, errorHandler: setVariableErrorCallback5
-	        };
-	    }
-	    
-	    function setVariableErrorCallback5(error) {
-	        InspectorTest.log("Expected error");
-	        
-	        // End of test.
-	        return;
-	    }
-    }
-}
-</script>
-</head>
-<body onLoad="runTest();">
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/inspector/syntax-highlight-css-expected.txt b/third_party/WebKit/LayoutTests/inspector/syntax-highlight-css-expected.txt
index 4ac8729..0c14fa20 100644
--- a/third_party/WebKit/LayoutTests/inspector/syntax-highlight-css-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector/syntax-highlight-css-expected.txt
@@ -7,7 +7,7 @@
 @import "/css/fireball_unicode.css"; html {}: cm-css-def, *, cm-css-string, *, cm-css-tag, *
 @media screen { body { color: red; } }: cm-css-def, *, cm-css-attribute, *, cm-css-tag, *, cm-css-property, *, cm-css-keyword, *
 @font-face { font-family: "MyHelvetica"; }: cm-css-def, *, cm-css-property, *, cm-css-string, *
-p { color: color; red: red; color: #000; color: #FFF; color: #123AbC; color: #faebfe; color:papayawhip; }: cm-css-tag, *, cm-css-property, *, cm-css-variable, *, cm-css-property, *, cm-css-variable-3, *, cm-css-property, *, cm-css-atom, *, cm-css-property, *, cm-css-atom, *, cm-css-property, *, cm-css-atom, *, cm-css-property, *, cm-css-atom, *, cm-css-property, *, cm-css-keyword, *
+p { color: color; red: red; color: #000; color: #FFF; color: #123AbC; color: #faebfe; color:papayawhip; }: cm-css-tag, *, cm-css-property, *, cm-css-atom, *, cm-css-property, *, cm-css-variable-3, *, cm-css-property, *, cm-css-atom, *, cm-css-property, *, cm-css-atom, *, cm-css-property, *, cm-css-atom, *, cm-css-property, *, cm-css-atom, *, cm-css-property, *, cm-css-keyword, *
 p { margin: -10px !important; }: cm-css-tag, *, cm-css-property, *, cm-css-number, *, cm-css-keyword, *
 $margin-left: $offsetBefore + 12px + $offsetAfter;: cm-css-variable-2, *, cm-css-variable-2, *, cm-css-number, *, cm-css-variable-2, *
 $type: monster;
@@ -45,5 +45,5 @@
 background-color: lighten($navbar-color, 10%);
 }
 }
-}: cm-css-builtin, *, *, cm-css-variable-2, *, cm-css-number, *, *, cm-css-variable-2, *, cm-css-number, *, *, cm-css-variable-2, *, cm-css-atom, *, *, cm-css-property, *, cm-css-variable-2, *, *, cm-css-property, *, cm-css-number, *, cm-css-atom, *, cm-css-variable-2, *, *, cm-css-tag, *, *, cm-css-def, *, cm-css-qualifier, *, cm-css-keyword, *, *, cm-css-property, *, cm-css-atom, *, *, cm-css-property, *, cm-css-variable-2, cm-css-operator, cm-css-variable-2, *, cm-css-number, *, *, cm-css-property, *, cm-css-variable, *, cm-css-variable-2, *, cm-css-number, *, *, *, cm-css-variable-3, *, *, cm-css-property, *, cm-css-variable, *, cm-css-variable-2, *, cm-css-number, *, *, *, *, *, *, *
+}: cm-css-builtin, *, *, cm-css-variable-2, *, cm-css-number, *, *, cm-css-variable-2, *, cm-css-number, *, *, cm-css-variable-2, *, cm-css-atom, *, *, cm-css-property, *, cm-css-variable-2, *, *, cm-css-property, *, cm-css-number, *, cm-css-atom, *, cm-css-variable-2, *, *, cm-css-tag, *, *, cm-css-def, *, cm-css-qualifier, *, cm-css-keyword, *, *, cm-css-property, *, cm-css-atom, *, *, cm-css-property, *, cm-css-variable-2, cm-css-operator, cm-css-variable-2, *, cm-css-number, *, *, cm-css-property, *, cm-css-atom, *, cm-css-variable-2, *, cm-css-number, *, *, *, cm-css-variable-3, *, *, cm-css-property, *, cm-css-atom, *, cm-css-variable-2, *, cm-css-number, *, *, *, *, *, *, *
 
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/text/combining-character-queries-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/text/combining-character-queries-expected.png
new file mode 100644
index 0000000..22b5ed59
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/svg/text/combining-character-queries-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/text/combining-character-queries-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/svg/text/combining-character-queries-expected.txt
new file mode 100644
index 0000000..452a44e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/svg/text/combining-character-queries-expected.txt
@@ -0,0 +1,538 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x521
+  LayoutBlockFlow {HTML} at (0,0) size 800x521
+    LayoutBlockFlow {BODY} at (8,8) size 784x505
+      LayoutSVGRoot {svg} at (44,19) size 410x358
+        LayoutSVGContainer {g} at (48,19) size 384x358
+          LayoutSVGRect {rect} at (58,19) size 18x49 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=50.00] [y=11.00] [width=18.00] [height=49.00]
+          LayoutSVGText {text} at (57,59) size 4x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (57.00,67.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (76,19) size 11x49 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=68.00] [y=11.00] [width=10.50] [height=49.00]
+          LayoutSVGText {text} at (71,59) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (71.25,67.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (86,19) size 11x49 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=78.50] [y=11.00] [width=10.50] [height=49.00]
+          LayoutSVGText {text} at (81,59) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (81.75,67.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (97,19) size 7x49 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=89.00] [y=11.00] [width=7.00] [height=49.00]
+          LayoutSVGText {text} at (90,59) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (90.50,67.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (104,19) size 7x49 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=96.00] [y=11.00] [width=7.00] [height=49.00]
+          LayoutSVGText {text} at (97,59) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (97.50,67.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (111,19) size 7x49 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=103.00] [y=11.00] [width=7.00] [height=49.00]
+          LayoutSVGText {text} at (104,59) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (104.50,67.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (208,26) size 16x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=200.00] [y=18.00] [width=16.00] [height=40.00]
+          LayoutSVGText {text} at (206,57) size 4x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (206.00,65.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (224,26) size 9x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=216.00] [y=18.00] [width=9.00] [height=40.00]
+          LayoutSVGText {text} at (218,57) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (218.50,65.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (233,26) size 9x40 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=225.00] [y=18.00] [width=9.00] [height=40.00]
+          LayoutSVGText {text} at (227,57) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (227.50,65.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (242,26) size 5x40 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=234.00] [y=18.00] [width=5.00] [height=40.00]
+          LayoutSVGText {text} at (234,57) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (234.50,65.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (247,26) size 5x40 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=239.00] [y=18.00] [width=5.00] [height=40.00]
+          LayoutSVGText {text} at (239,57) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (239.50,65.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (252,26) size 5x40 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=244.00] [y=18.00] [width=5.00] [height=40.00]
+          LayoutSVGText {text} at (244,57) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (244.50,65.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (358,26) size 18x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=350.00] [y=18.00] [width=18.00] [height=40.00]
+          LayoutSVGText {text} at (357,57) size 4x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (357.00,65.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (376,26) size 10x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=368.00] [y=18.00] [width=9.50] [height=40.00]
+          LayoutSVGText {text} at (370,57) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (370.75,65.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (385,26) size 10x40 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=377.50] [y=18.00] [width=9.50] [height=40.00]
+          LayoutSVGText {text} at (380,57) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (380.25,65.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (395,26) size 6x40 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=387.00] [y=18.00] [width=6.00] [height=40.00]
+          LayoutSVGText {text} at (388,57) size 4x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (388.00,65.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (401,26) size 6x40 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=393.00] [y=18.00] [width=6.00] [height=40.00]
+          LayoutSVGText {text} at (394,57) size 4x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (394.00,65.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (407,26) size 6x40 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=399.00] [y=18.00] [width=6.00] [height=40.00]
+          LayoutSVGText {text} at (400,57) size 4x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (400.00,65.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (8,8) size 0x0 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=100.00] [y=86.00] [width=0.00] [height=49.00]
+          LayoutSVGText {text} at (98,134) size 4x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (98.00,142.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (90,94) size 18x49 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=82.00] [y=86.00] [width=18.00] [height=49.00]
+          LayoutSVGText {text} at (89,134) size 4x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (89.00,142.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (8,8) size 0x0 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=82.00] [y=86.00] [width=0.00] [height=49.00]
+          LayoutSVGText {text} at (80,134) size 4x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (80.00,142.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (69,94) size 11x49 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=61.00] [y=86.00] [width=10.50] [height=49.00]
+          LayoutSVGText {text} at (64,134) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (64.25,142.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (79,94) size 11x49 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=71.50] [y=86.00] [width=10.50] [height=49.00]
+          LayoutSVGText {text} at (74,134) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (74.75,142.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (8,8) size 0x0 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=61.00] [y=86.00] [width=0.00] [height=49.00]
+          LayoutSVGText {text} at (59,134) size 4x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (59.00,142.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (48,94) size 7x49 [fill={[type=SOLID] [color=#EE82EE] [opacity=0.30]}] [x=40.00] [y=86.00] [width=7.00] [height=49.00]
+          LayoutSVGText {text} at (41,134) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (41.50,142.00) startOffset 0 endOffset 1 width 4.00: "6"
+          LayoutSVGRect {rect} at (55,94) size 7x49 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=47.00] [y=86.00] [width=7.00] [height=49.00]
+          LayoutSVGText {text} at (48,134) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (48.50,142.00) startOffset 0 endOffset 1 width 4.00: "7"
+          LayoutSVGRect {rect} at (62,94) size 7x49 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=54.00] [y=86.00] [width=7.00] [height=49.00]
+          LayoutSVGText {text} at (55,134) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (55.50,142.00) startOffset 0 endOffset 1 width 4.00: "8"
+          LayoutSVGRect {rect} at (8,8) size 0x0 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=250.00] [y=93.00] [width=0.00] [height=40.00]
+          LayoutSVGText {text} at (248,132) size 4x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (248.00,140.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (242,101) size 16x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=234.00] [y=93.00] [width=16.00] [height=40.00]
+          LayoutSVGText {text} at (240,132) size 4x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (240.00,140.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (8,8) size 0x0 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=234.00] [y=93.00] [width=0.00] [height=40.00]
+          LayoutSVGText {text} at (232,132) size 4x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (232.00,140.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (224,101) size 9x40 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=216.00] [y=93.00] [width=9.00] [height=40.00]
+          LayoutSVGText {text} at (218,132) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (218.50,140.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (233,101) size 9x40 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=225.00] [y=93.00] [width=9.00] [height=40.00]
+          LayoutSVGText {text} at (227,132) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (227.50,140.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (8,8) size 0x0 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=216.00] [y=93.00] [width=0.00] [height=40.00]
+          LayoutSVGText {text} at (214,132) size 4x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (214.00,140.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (209,101) size 5x40 [fill={[type=SOLID] [color=#EE82EE] [opacity=0.30]}] [x=201.00] [y=93.00] [width=5.00] [height=40.00]
+          LayoutSVGText {text} at (201,132) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (201.50,140.00) startOffset 0 endOffset 1 width 4.00: "6"
+          LayoutSVGRect {rect} at (214,101) size 5x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=206.00] [y=93.00] [width=5.00] [height=40.00]
+          LayoutSVGText {text} at (206,132) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (206.50,140.00) startOffset 0 endOffset 1 width 4.00: "7"
+          LayoutSVGRect {rect} at (219,101) size 5x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=211.00] [y=93.00] [width=5.00] [height=40.00]
+          LayoutSVGText {text} at (211,132) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (211.50,140.00) startOffset 0 endOffset 1 width 4.00: "8"
+          LayoutSVGRect {rect} at (8,8) size 0x0 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=400.00] [y=93.00] [width=0.00] [height=40.00]
+          LayoutSVGText {text} at (398,132) size 4x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (398.00,140.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (390,101) size 18x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=382.00] [y=93.00] [width=18.00] [height=40.00]
+          LayoutSVGText {text} at (389,132) size 4x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (389.00,140.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (8,8) size 0x0 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=382.00] [y=93.00] [width=0.00] [height=40.00]
+          LayoutSVGText {text} at (380,132) size 4x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (380.00,140.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (371,101) size 10x40 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=363.00] [y=93.00] [width=9.50] [height=40.00]
+          LayoutSVGText {text} at (365,132) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (365.75,140.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (380,101) size 10x40 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=372.50] [y=93.00] [width=9.50] [height=40.00]
+          LayoutSVGText {text} at (375,132) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (375.25,140.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (8,8) size 0x0 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=363.00] [y=93.00] [width=0.00] [height=40.00]
+          LayoutSVGText {text} at (361,132) size 4x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (361.00,140.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (353,101) size 6x40 [fill={[type=SOLID] [color=#EE82EE] [opacity=0.30]}] [x=345.00] [y=93.00] [width=6.00] [height=40.00]
+          LayoutSVGText {text} at (346,132) size 4x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (346.00,140.00) startOffset 0 endOffset 1 width 4.00: "6"
+          LayoutSVGRect {rect} at (359,101) size 6x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=351.00] [y=93.00] [width=6.00] [height=40.00]
+          LayoutSVGText {text} at (352,132) size 4x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (352.00,140.00) startOffset 0 endOffset 1 width 4.00: "7"
+          LayoutSVGRect {rect} at (365,101) size 6x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=357.00] [y=93.00] [width=6.00] [height=40.00]
+          LayoutSVGText {text} at (358,132) size 4x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (358.00,140.00) startOffset 0 endOffset 1 width 4.00: "8"
+          LayoutSVGRect {rect} at (58,169) size 11x49 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=50.00] [y=161.00] [width=11.00] [height=49.00]
+          LayoutSVGText {text} at (53,209) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (53.50,217.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (69,169) size 5x49 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=61.00] [y=161.00] [width=4.50] [height=49.00]
+          LayoutSVGText {text} at (61,209) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (61.25,217.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (73,169) size 5x49 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=65.50] [y=161.00] [width=4.50] [height=49.00]
+          LayoutSVGText {text} at (65,209) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (65.75,217.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (78,169) size 10x49 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=70.00] [y=161.00] [width=10.00] [height=49.00]
+          LayoutSVGText {text} at (73,209) size 4x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (73.00,217.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (88,169) size 18x49 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=80.00] [y=161.00] [width=18.00] [height=49.00]
+          LayoutSVGText {text} at (87,209) size 4x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (87.00,217.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (106,169) size 18x49 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=98.00] [y=161.00] [width=18.00] [height=49.00]
+          LayoutSVGText {text} at (105,209) size 4x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (105.00,217.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (124,169) size 4x49 [fill={[type=SOLID] [color=#EE82EE] [opacity=0.30]}] [x=116.00] [y=161.00] [width=3.33] [height=49.00]
+          LayoutSVGText {text} at (115,209) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (115.67,217.00) startOffset 0 endOffset 1 width 4.00: "6"
+          LayoutSVGRect {rect} at (127,169) size 4x49 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=119.33] [y=161.00] [width=3.33] [height=49.00]
+          LayoutSVGText {text} at (119,209) size 4x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (119.00,217.00) startOffset 0 endOffset 1 width 4.00: "7"
+          LayoutSVGRect {rect} at (130,169) size 5x49 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=122.67] [y=161.00] [width=3.33] [height=49.00]
+          LayoutSVGText {text} at (122,209) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (122.33,217.00) startOffset 0 endOffset 1 width 4.00: "8"
+          LayoutSVGRect {rect} at (208,176) size 11x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=200.00] [y=168.00] [width=11.00] [height=40.00]
+          LayoutSVGText {text} at (203,207) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (203.50,215.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (219,176) size 5x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=211.00] [y=168.00] [width=4.50] [height=40.00]
+          LayoutSVGText {text} at (211,207) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (211.25,215.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (223,176) size 5x40 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=215.50] [y=168.00] [width=4.50] [height=40.00]
+          LayoutSVGText {text} at (215,207) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (215.75,215.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (228,176) size 9x40 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=220.00] [y=168.00] [width=9.00] [height=40.00]
+          LayoutSVGText {text} at (222,207) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (222.50,215.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (237,176) size 11x40 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=229.00] [y=168.00] [width=10.68] [height=40.00]
+          LayoutSVGText {text} at (232,207) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (232.34,215.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (247,176) size 12x40 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=239.68] [y=168.00] [width=10.68] [height=40.00]
+          LayoutSVGText {text} at (243,207) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (243.03,215.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (258,176) size 4x40 [fill={[type=SOLID] [color=#EE82EE] [opacity=0.30]}] [x=250.37] [y=168.00] [width=3.00] [height=40.00]
+          LayoutSVGText {text} at (249,207) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (249.87,215.00) startOffset 0 endOffset 1 width 4.00: "6"
+          LayoutSVGRect {rect} at (261,176) size 4x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=253.37] [y=168.00] [width=3.00] [height=40.00]
+          LayoutSVGText {text} at (252,207) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (252.87,215.00) startOffset 0 endOffset 1 width 4.00: "7"
+          LayoutSVGRect {rect} at (264,176) size 4x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=256.37] [y=168.00] [width=3.00] [height=40.00]
+          LayoutSVGText {text} at (255,207) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (255.87,215.00) startOffset 0 endOffset 1 width 4.00: "8"
+          LayoutSVGRect {rect} at (358,176) size 10x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=350.00] [y=168.00] [width=10.00] [height=40.00]
+          LayoutSVGText {text} at (353,207) size 4x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (353.00,215.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (368,176) size 4x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=360.00] [y=168.00] [width=3.50] [height=40.00]
+          LayoutSVGText {text} at (359,207) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (359.75,215.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (371,176) size 4x40 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=363.50] [y=168.00] [width=3.50] [height=40.00]
+          LayoutSVGText {text} at (363,207) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (363.25,215.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (375,176) size 10x40 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=367.00] [y=168.00] [width=10.00] [height=40.00]
+          LayoutSVGText {text} at (370,207) size 4x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (370.00,215.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (385,176) size 10x40 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=377.00] [y=168.00] [width=9.68] [height=40.00]
+          LayoutSVGText {text} at (379,207) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (379.84,215.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (394,176) size 11x40 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=386.68] [y=168.00] [width=9.68] [height=40.00]
+          LayoutSVGText {text} at (389,207) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (389.53,215.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (404,176) size 3x40 [fill={[type=SOLID] [color=#EE82EE] [opacity=0.30]}] [x=396.37] [y=168.00] [width=2.33] [height=40.00]
+          LayoutSVGText {text} at (395,207) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (395.53,215.00) startOffset 0 endOffset 1 width 4.00: "6"
+          LayoutSVGRect {rect} at (406,176) size 4x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=398.70] [y=168.00] [width=2.33] [height=40.00]
+          LayoutSVGText {text} at (397,207) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (397.87,215.00) startOffset 0 endOffset 1 width 4.00: "7"
+          LayoutSVGRect {rect} at (409,176) size 3x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=401.03] [y=168.00] [width=2.33] [height=40.00]
+          LayoutSVGText {text} at (400,207) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (400.20,215.00) startOffset 0 endOffset 1 width 4.00: "8"
+          LayoutSVGRect {rect} at (58,244) size 18x49 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=50.00] [y=236.00] [width=18.00] [height=49.00]
+          LayoutSVGText {text} at (57,284) size 4x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (57.00,292.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (76,244) size 9x49 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=68.00] [y=236.00] [width=9.00] [height=49.00]
+          LayoutSVGText {text} at (70,284) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (70.50,292.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (85,244) size 9x49 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=77.00] [y=236.00] [width=9.00] [height=49.00]
+          LayoutSVGText {text} at (79,284) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (79.50,292.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (122,244) size 7x49 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=114.00] [y=236.00] [width=7.00] [height=49.00]
+          LayoutSVGText {text} at (115,284) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (115.50,292.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (115,244) size 7x49 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=107.00] [y=236.00] [width=7.00] [height=49.00]
+          LayoutSVGText {text} at (108,284) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (108.50,292.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (104,244) size 11x49 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=96.50] [y=236.00] [width=10.50] [height=49.00]
+          LayoutSVGText {text} at (99,284) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (99.75,292.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (94,244) size 11x49 [fill={[type=SOLID] [color=#EE82EE] [opacity=0.30]}] [x=86.00] [y=236.00] [width=10.50] [height=49.00]
+          LayoutSVGText {text} at (89,284) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (89.25,292.00) startOffset 0 endOffset 1 width 4.00: "6"
+          LayoutSVGRect {rect} at (129,244) size 18x49 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=121.00] [y=236.00] [width=18.00] [height=49.00]
+          LayoutSVGText {text} at (128,284) size 4x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (128.00,292.00) startOffset 0 endOffset 1 width 4.00: "7"
+          LayoutSVGRect {rect} at (147,244) size 9x49 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=139.00] [y=236.00] [width=9.00] [height=49.00]
+          LayoutSVGText {text} at (141,284) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (141.50,292.00) startOffset 0 endOffset 1 width 4.00: "8"
+          LayoutSVGRect {rect} at (156,244) size 9x49 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=148.00] [y=236.00] [width=9.00] [height=49.00]
+          LayoutSVGText {text} at (150,284) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (150.50,292.00) startOffset 0 endOffset 1 width 4.00: "9"
+          LayoutSVGRect {rect} at (208,251) size 11x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=200.00] [y=243.00] [width=10.68] [height=40.00]
+          LayoutSVGText {text} at (203,282) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (203.34,290.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (218,251) size 7x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=210.68] [y=243.00] [width=5.34] [height=40.00]
+          LayoutSVGText {text} at (211,282) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (211.35,290.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (224,251) size 6x40 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=216.03] [y=243.00] [width=5.34] [height=40.00]
+          LayoutSVGText {text} at (216,282) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (216.70,290.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (257,251) size 8x40 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=249.37] [y=243.00] [width=7.00] [height=40.00]
+          LayoutSVGText {text} at (250,282) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (250.87,290.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (250,251) size 8x40 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=242.37] [y=243.00] [width=7.00] [height=40.00]
+          LayoutSVGText {text} at (243,282) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (243.87,290.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (239,251) size 12x40 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=231.87] [y=243.00] [width=10.50] [height=40.00]
+          LayoutSVGText {text} at (235,282) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (235.12,290.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (229,251) size 11x40 [fill={[type=SOLID] [color=#EE82EE] [opacity=0.30]}] [x=221.37] [y=243.00] [width=10.50] [height=40.00]
+          LayoutSVGText {text} at (224,282) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (224.62,290.00) startOffset 0 endOffset 1 width 4.00: "6"
+          LayoutSVGRect {rect} at (264,251) size 12x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=256.37] [y=243.00] [width=10.68] [height=40.00]
+          LayoutSVGText {text} at (259,282) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (259.71,290.00) startOffset 0 endOffset 1 width 4.00: "7"
+          LayoutSVGRect {rect} at (275,251) size 6x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=267.05] [y=243.00] [width=5.34] [height=40.00]
+          LayoutSVGText {text} at (267,282) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (267.72,290.00) startOffset 0 endOffset 1 width 4.00: "8"
+          LayoutSVGRect {rect} at (280,251) size 6x40 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=272.39] [y=243.00] [width=5.34] [height=40.00]
+          LayoutSVGText {text} at (273,282) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (273.06,290.00) startOffset 0 endOffset 1 width 4.00: "9"
+          LayoutSVGRect {rect} at (358,251) size 10x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=350.00] [y=243.00] [width=9.68] [height=40.00]
+          LayoutSVGText {text} at (352,282) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (352.84,290.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (367,251) size 6x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=359.68] [y=243.00] [width=4.84] [height=40.00]
+          LayoutSVGText {text} at (360,282) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (360.10,290.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (372,251) size 6x40 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=364.53] [y=243.00] [width=4.84] [height=40.00]
+          LayoutSVGText {text} at (364,282) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (364.95,290.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (405,251) size 8x40 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=397.37] [y=243.00] [width=7.00] [height=40.00]
+          LayoutSVGText {text} at (398,282) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (398.87,290.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (398,251) size 8x40 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=390.37] [y=243.00] [width=7.00] [height=40.00]
+          LayoutSVGText {text} at (391,282) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (391.87,290.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (387,251) size 12x40 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=379.87] [y=243.00] [width=10.50] [height=40.00]
+          LayoutSVGText {text} at (383,282) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (383.12,290.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (377,251) size 11x40 [fill={[type=SOLID] [color=#EE82EE] [opacity=0.30]}] [x=369.37] [y=243.00] [width=10.50] [height=40.00]
+          LayoutSVGText {text} at (372,282) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (372.62,290.00) startOffset 0 endOffset 1 width 4.00: "6"
+          LayoutSVGRect {rect} at (412,251) size 11x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=404.37] [y=243.00] [width=9.68] [height=40.00]
+          LayoutSVGText {text} at (407,282) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (407.21,290.00) startOffset 0 endOffset 1 width 4.00: "7"
+          LayoutSVGRect {rect} at (422,251) size 5x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=414.05] [y=243.00] [width=4.84] [height=40.00]
+          LayoutSVGText {text} at (414,282) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (414.47,290.00) startOffset 0 endOffset 1 width 4.00: "8"
+          LayoutSVGRect {rect} at (426,251) size 6x40 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=418.89] [y=243.00] [width=4.84] [height=40.00]
+          LayoutSVGText {text} at (419,282) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (419.31,290.00) startOffset 0 endOffset 1 width 4.00: "9"
+          LayoutSVGRect {rect} at (58,319) size 5x49 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=50.00] [y=311.00] [width=5.00] [height=49.00]
+          LayoutSVGText {text} at (50,359) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (50.50,367.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (63,319) size 17x49 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=55.00] [y=311.00] [width=17.00] [height=49.00]
+          LayoutSVGText {text} at (61,359) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (61.50,367.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (80,319) size 5x49 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=72.00] [y=311.00] [width=5.00] [height=49.00]
+          LayoutSVGText {text} at (72,359) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (72.50,367.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (85,319) size 5x49 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=77.00] [y=311.00] [width=5.00] [height=49.00]
+          LayoutSVGText {text} at (77,359) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (77.50,367.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (208,326) size 5x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=200.00] [y=318.00] [width=4.50] [height=40.00]
+          LayoutSVGText {text} at (200,357) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (200.25,365.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (212,326) size 28x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=204.50] [y=318.00] [width=27.00] [height=40.00]
+          LayoutSVGText {text} at (216,357) size 4x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (216.00,365.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (239,326) size 5x40 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=231.50] [y=318.00] [width=4.50] [height=40.00]
+          LayoutSVGText {text} at (231,357) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (231.75,365.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (244,326) size 5x40 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=236.00] [y=318.00] [width=4.50] [height=40.00]
+          LayoutSVGText {text} at (236,357) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (236.25,365.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (358,326) size 5x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=350.00] [y=318.00] [width=5.00] [height=40.00]
+          LayoutSVGText {text} at (350,357) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (350.50,365.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (363,326) size 26x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=355.00] [y=318.00] [width=26.00] [height=40.00]
+          LayoutSVGText {text} at (366,357) size 4x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (366.00,365.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (389,326) size 4x40 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=381.00] [y=318.00] [width=3.50] [height=40.00]
+          LayoutSVGText {text} at (380,357) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (380.75,365.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (392,326) size 4x40 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=384.50] [y=318.00] [width=3.50] [height=40.00]
+          LayoutSVGText {text} at (384,357) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (384.25,365.00) startOffset 0 endOffset 1 width 4.00: "3"
+        LayoutSVGContainer {g} at (44,19) size 410x349
+          LayoutSVGText {text} at (50,11) size 60x49 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 60x49
+              chunk 1 text run 1 at (50.00,50.00) startOffset 0 endOffset 6 width 60.00: "ab\x{30C}c\x{30C}\x{30C}"
+          LayoutSVGText {text} at (200,18) size 56x40 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 56x40
+              chunk 1 text run 1 at (200.00,50.00) startOffset 0 endOffset 6 width 49.00: "ab\x{30C}c\x{30C}\x{30C}"
+          LayoutSVGText {text} at (350,18) size 59x40 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 59x40
+              chunk 1 text run 1 at (350.00,50.00) startOffset 0 endOffset 6 width 55.00: "ab\x{30C}c\x{30C}\x{30C}"
+          LayoutSVGText {text} at (40,86) size 60x49 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 60x49
+              chunk 1 text run 1 at (40.00,125.00) startOffset 0 endOffset 3 width 21.00: "c\x{30C}\x{30C}"
+              chunk 1 text run 1 at (61.00,125.00) startOffset 0 endOffset 1 width 0.00 RTL: "\x{200F}"
+              chunk 1 text run 1 at (61.00,125.00) startOffset 0 endOffset 2 width 21.00: "b\x{30C}"
+              chunk 1 text run 1 at (82.00,125.00) startOffset 0 endOffset 1 width 0.00 RTL: "\x{200F}"
+              chunk 1 text run 1 at (82.00,125.00) startOffset 0 endOffset 1 width 18.00: "a"
+              chunk 1 text run 1 at (100.00,125.00) startOffset 0 endOffset 1 width 0.00 RTL: "\x{200F}"
+          LayoutSVGText {text} at (201,93) size 55x40 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 55x40
+              chunk 1 text run 1 at (201.00,125.00) startOffset 0 endOffset 3 width 15.00: "c\x{30C}\x{30C}"
+              chunk 1 text run 1 at (216.00,125.00) startOffset 0 endOffset 1 width 0.00 RTL: "\x{200F}"
+              chunk 1 text run 1 at (216.00,125.00) startOffset 0 endOffset 2 width 18.00: "b\x{30C}"
+              chunk 1 text run 1 at (234.00,125.00) startOffset 0 endOffset 1 width 0.00 RTL: "\x{200F}"
+              chunk 1 text run 1 at (234.00,125.00) startOffset 0 endOffset 1 width 16.00: "a"
+              chunk 1 text run 1 at (250.00,125.00) startOffset 0 endOffset 1 width 0.00 RTL: "\x{200F}"
+          LayoutSVGText {text} at (345,93) size 59x40 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 59x40
+              chunk 1 text run 1 at (345.00,125.00) startOffset 0 endOffset 3 width 18.00: "c\x{30C}\x{30C}"
+              chunk 1 text run 1 at (363.00,125.00) startOffset 0 endOffset 1 width 0.00 RTL: "\x{200F}"
+              chunk 1 text run 1 at (363.00,125.00) startOffset 0 endOffset 2 width 19.00: "b\x{30C}"
+              chunk 1 text run 1 at (382.00,125.00) startOffset 0 endOffset 1 width 0.00 RTL: "\x{200F}"
+              chunk 1 text run 1 at (382.00,125.00) startOffset 0 endOffset 1 width 18.00: "a"
+              chunk 1 text run 1 at (400.00,125.00) startOffset 0 endOffset 1 width 0.00 RTL: "\x{200F}"
+          LayoutSVGText {text} at (50,144) size 91x66 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 91x66
+              chunk 1 text run 1 at (50.00,200.00) startOffset 0 endOffset 9 width 76.00: "fi\x{30C} ffi\x{30C}\x{30C}"
+          LayoutSVGText {text} at (200,168) size 82x40 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 82x40
+              chunk 1 text run 1 at (200.00,200.00) startOffset 0 endOffset 9 width 59.37: "fi\x{30C} ffi\x{30C}\x{30C}"
+          LayoutSVGText {text} at (350,168) size 76x40 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 76x40
+              chunk 1 text run 1 at (350.00,200.00) startOffset 0 endOffset 9 width 53.37: "fi\x{30C} ffi\x{30C}\x{30C}"
+          LayoutSVGText {text} at (50,236) size 122x49 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 122x49
+              chunk 1 text run 1 at (50.00,275.00) startOffset 0 endOffset 3 width 36.00: "ff\x{30C}"
+              chunk 1 text run 1 at (86.00,275.00) startOffset 0 endOffset 4 width 35.00 RTL: "\x{640}\x{640}\x{644}\x{627}"
+              chunk 1 text run 1 at (121.00,275.00) startOffset 0 endOffset 3 width 36.00: "ff\x{30C}"
+          LayoutSVGText {text} at (200,243) size 100x40 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 100x40
+              chunk 1 text run 1 at (200.00,275.00) startOffset 0 endOffset 3 width 21.37: "ff\x{30C}"
+              chunk 1 text run 1 at (221.37,275.00) startOffset 0 endOffset 4 width 35.00 RTL: "\x{640}\x{640}\x{644}\x{627}"
+              chunk 1 text run 1 at (256.37,275.00) startOffset 0 endOffset 3 width 21.37: "ff\x{30C}"
+          LayoutSVGText {text} at (350,243) size 96x40 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 96x40
+              chunk 1 text run 1 at (350.00,275.00) startOffset 0 endOffset 3 width 19.37: "ff\x{30C}"
+              chunk 1 text run 1 at (369.37,275.00) startOffset 0 endOffset 4 width 35.00 RTL: "\x{640}\x{640}\x{644}\x{627}"
+              chunk 1 text run 1 at (404.37,275.00) startOffset 0 endOffset 3 width 19.37: "ff\x{30C}"
+          LayoutSVGText {text} at (36,311) size 61x49 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 61x49
+              chunk 1 text run 1 at (50.00,350.00) startOffset 0 endOffset 1 width 5.00: "\x{30C}"
+              chunk 1 text run 1 at (55.00,350.00) startOffset 0 endOffset 1 width 17.00 RTL: "\x{FDB0}"
+              chunk 1 text run 1 at (72.00,350.00) startOffset 0 endOffset 2 width 10.00: "i\x{333}"
+          LayoutSVGText {text} at (186,318) size 77x40 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 77x40
+              chunk 1 text run 1 at (200.00,350.00) startOffset 0 endOffset 1 width 4.50: "\x{30C}"
+              chunk 1 text run 1 at (204.50,350.00) startOffset 0 endOffset 1 width 27.00 RTL: "\x{FDB0}"
+              chunk 1 text run 1 at (231.50,350.00) startOffset 0 endOffset 2 width 9.00: "i\x{333}"
+          LayoutSVGText {text} at (336,318) size 74x40 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 74x40
+              chunk 1 text run 1 at (350.00,350.00) startOffset 0 endOffset 1 width 5.00: "\x{30C}"
+              chunk 1 text run 1 at (355.00,350.00) startOffset 0 endOffset 1 width 26.00 RTL: "\x{FDB0}"
+              chunk 1 text run 1 at (381.00,350.00) startOffset 0 endOffset 2 width 7.00: "i\x{333}"
+      LayoutText {#text} at (0,0) size 0x0
+      LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/svg/text/combining-character-queries-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/svg/text/combining-character-queries-expected.png
new file mode 100644
index 0000000..049e636
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/svg/text/combining-character-queries-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/svg/text/combining-character-queries-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/svg/text/combining-character-queries-expected.txt
new file mode 100644
index 0000000..2bbed503
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/svg/text/combining-character-queries-expected.txt
@@ -0,0 +1,538 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x520
+  LayoutBlockFlow {HTML} at (0,0) size 800x520
+    LayoutBlockFlow {BODY} at (8,8) size 784x504
+      LayoutSVGRoot {svg} at (50,18) size 391x365
+        LayoutSVGContainer {g} at (56,19) size 385x364
+          LayoutSVGRect {rect} at (58,19) size 18x55 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=50.00] [y=11.00] [width=17.96] [height=55.00]
+          LayoutSVGText {text} at (56,66) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (56.98,73.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (75,19) size 10x55 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=67.96] [y=11.00] [width=8.49] [height=55.00]
+          LayoutSVGText {text} at (70,66) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (70.20,73.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (84,19) size 9x55 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=76.45] [y=11.00] [width=8.49] [height=55.00]
+          LayoutSVGText {text} at (78,66) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (78.69,73.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (92,19) size 6x55 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=84.93] [y=11.00] [width=4.47] [height=55.00]
+          LayoutSVGText {text} at (85,66) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (85.16,73.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (97,19) size 5x55 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=89.40] [y=11.00] [width=4.47] [height=55.00]
+          LayoutSVGText {text} at (89,66) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (89.63,73.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (101,19) size 6x55 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=93.86] [y=11.00] [width=4.47] [height=55.00]
+          LayoutSVGText {text} at (94,66) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (94.10,73.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (208,27) size 16x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=200.00] [y=19.00] [width=15.53] [height=40.00]
+          LayoutSVGText {text} at (205,59) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (205.77,66.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (223,27) size 10x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=215.53] [y=19.00] [width=8.75] [height=40.00]
+          LayoutSVGText {text} at (217,59) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (217.91,66.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (232,27) size 10x40 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=224.28] [y=19.00] [width=8.75] [height=40.00]
+          LayoutSVGText {text} at (226,59) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (226.66,66.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (241,27) size 6x40 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=233.03] [y=19.00] [width=5.18] [height=40.00]
+          LayoutSVGText {text} at (233,59) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (233.62,66.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (246,27) size 6x40 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=238.21] [y=19.00] [width=5.18] [height=40.00]
+          LayoutSVGText {text} at (238,59) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (238.80,66.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (251,27) size 6x40 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=243.39] [y=19.00] [width=5.18] [height=40.00]
+          LayoutSVGText {text} at (243,59) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (243.98,66.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (358,26) size 20x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=350.00] [y=18.00] [width=19.47] [height=40.00]
+          LayoutSVGText {text} at (357,58) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (357.73,65.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (377,26) size 11x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=369.47] [y=18.00] [width=9.73] [height=40.00]
+          LayoutSVGText {text} at (372,58) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (372.33,65.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (387,26) size 10x40 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=379.20] [y=18.00] [width=9.73] [height=40.00]
+          LayoutSVGText {text} at (382,58) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (382.06,65.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (396,26) size 8x40 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=388.93] [y=18.00] [width=6.19] [height=40.00]
+          LayoutSVGText {text} at (390,58) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (390.03,65.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (403,26) size 7x40 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=395.12] [y=18.00] [width=6.19] [height=40.00]
+          LayoutSVGText {text} at (396,58) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (396.22,65.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (409,26) size 7x40 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=401.32] [y=18.00] [width=6.19] [height=40.00]
+          LayoutSVGText {text} at (402,58) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (402.41,65.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (8,8) size 0x0 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=100.00] [y=86.00] [width=0.00] [height=55.00]
+          LayoutSVGText {text} at (97,141) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (98.00,148.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (90,94) size 18x55 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=82.04] [y=86.00] [width=17.96] [height=55.00]
+          LayoutSVGText {text} at (89,141) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (89.02,148.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (8,8) size 0x0 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=82.04] [y=86.00] [width=0.00] [height=55.00]
+          LayoutSVGText {text} at (80,141) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (80.04,148.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (73,94) size 9x55 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=65.07] [y=86.00] [width=8.49] [height=55.00]
+          LayoutSVGText {text} at (67,141) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (67.31,148.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (81,94) size 10x55 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=73.55] [y=86.00] [width=8.49] [height=55.00]
+          LayoutSVGText {text} at (75,141) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (75.80,148.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (8,8) size 0x0 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=65.07] [y=86.00] [width=0.00] [height=55.00]
+          LayoutSVGText {text} at (63,141) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (63.07,148.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (59,94) size 6x55 [fill={[type=SOLID] [color=#EE82EE] [opacity=0.30]}] [x=51.67] [y=86.00] [width=4.47] [height=55.00]
+          LayoutSVGText {text} at (51,141) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (51.90,148.00) startOffset 0 endOffset 1 width 4.00: "6"
+          LayoutSVGRect {rect} at (64,94) size 5x55 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=56.14] [y=86.00] [width=4.47] [height=55.00]
+          LayoutSVGText {text} at (56,141) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (56.37,148.00) startOffset 0 endOffset 1 width 4.00: "7"
+          LayoutSVGRect {rect} at (68,94) size 6x55 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=60.60] [y=86.00] [width=4.47] [height=55.00]
+          LayoutSVGText {text} at (60,141) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (60.84,148.00) startOffset 0 endOffset 1 width 4.00: "8"
+          LayoutSVGRect {rect} at (8,8) size 0x0 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=250.00] [y=94.00] [width=0.00] [height=40.00]
+          LayoutSVGText {text} at (248,134) size 4x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (248.00,141.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (242,102) size 16x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=234.47] [y=94.00] [width=15.53] [height=40.00]
+          LayoutSVGText {text} at (240,134) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (240.23,141.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (8,8) size 0x0 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=234.47] [y=94.00] [width=0.00] [height=40.00]
+          LayoutSVGText {text} at (232,134) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (232.47,141.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (224,102) size 10x40 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=216.97] [y=94.00] [width=8.75] [height=40.00]
+          LayoutSVGText {text} at (219,134) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (219.34,141.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (233,102) size 10x40 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=225.72] [y=94.00] [width=8.75] [height=40.00]
+          LayoutSVGText {text} at (228,134) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (228.09,141.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (8,8) size 0x0 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=216.97] [y=94.00] [width=0.00] [height=40.00]
+          LayoutSVGText {text} at (214,134) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (214.97,141.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (209,102) size 6x40 [fill={[type=SOLID] [color=#EE82EE] [opacity=0.30]}] [x=201.43] [y=94.00] [width=5.18] [height=40.00]
+          LayoutSVGText {text} at (202,134) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (202.02,141.00) startOffset 0 endOffset 1 width 4.00: "6"
+          LayoutSVGRect {rect} at (214,102) size 6x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=206.61] [y=94.00] [width=5.18] [height=40.00]
+          LayoutSVGText {text} at (207,134) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (207.20,141.00) startOffset 0 endOffset 1 width 4.00: "7"
+          LayoutSVGRect {rect} at (219,102) size 6x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=211.79] [y=94.00] [width=5.18] [height=40.00]
+          LayoutSVGText {text} at (212,134) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (212.38,141.00) startOffset 0 endOffset 1 width 4.00: "8"
+          LayoutSVGRect {rect} at (8,8) size 0x0 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=400.00] [y=93.00] [width=0.00] [height=40.00]
+          LayoutSVGText {text} at (398,133) size 4x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (398.00,140.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (388,101) size 20x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=380.53] [y=93.00] [width=19.47] [height=40.00]
+          LayoutSVGText {text} at (388,133) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (388.27,140.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (8,8) size 0x0 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=380.53] [y=93.00] [width=0.00] [height=40.00]
+          LayoutSVGText {text} at (378,133) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (378.53,140.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (368,101) size 11x40 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=360.73] [y=93.00] [width=9.90] [height=40.00]
+          LayoutSVGText {text} at (363,133) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (363.68,140.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (378,101) size 11x40 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=370.63] [y=93.00] [width=9.90] [height=40.00]
+          LayoutSVGText {text} at (373,133) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (373.58,140.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (8,8) size 0x0 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=360.73] [y=93.00] [width=0.00] [height=40.00]
+          LayoutSVGText {text} at (358,133) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (358.73,140.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (350,101) size 7x40 [fill={[type=SOLID] [color=#EE82EE] [opacity=0.30]}] [x=342.15] [y=93.00] [width=6.19] [height=40.00]
+          LayoutSVGText {text} at (343,133) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (343.25,140.00) startOffset 0 endOffset 1 width 4.00: "6"
+          LayoutSVGRect {rect} at (356,101) size 7x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=348.34] [y=93.00] [width=6.19] [height=40.00]
+          LayoutSVGText {text} at (349,133) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (349.44,140.00) startOffset 0 endOffset 1 width 4.00: "7"
+          LayoutSVGRect {rect} at (362,101) size 7x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=354.54] [y=93.00] [width=6.19] [height=40.00]
+          LayoutSVGText {text} at (355,133) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (355.63,140.00) startOffset 0 endOffset 1 width 4.00: "8"
+          LayoutSVGRect {rect} at (58,169) size 6x55 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=50.00] [y=161.00] [width=5.97] [height=55.00]
+          LayoutSVGText {text} at (50,216) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (50.99,223.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (63,169) size 18x55 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=55.97] [y=161.00] [width=16.27] [height=55.00]
+          LayoutSVGText {text} at (62,216) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (62.11,223.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (80,169) size 17x55 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=72.24] [y=161.00] [width=16.27] [height=55.00]
+          LayoutSVGText {text} at (78,216) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (78.37,223.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (96,169) size 11x55 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=88.50] [y=161.00] [width=9.72] [height=55.00]
+          LayoutSVGText {text} at (91,216) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (91.37,223.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (106,169) size 1x55 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=98.23] [y=161.00] [width=0.42] [height=55.00]
+          LayoutSVGText {text} at (96,216) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (96.44,223.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (106,169) size 2x55 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=98.65] [y=161.00] [width=0.42] [height=55.00]
+          LayoutSVGText {text} at (96,216) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (96.86,223.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (107,169) size 13x55 [fill={[type=SOLID] [color=#EE82EE] [opacity=0.30]}] [x=99.06] [y=161.00] [width=12.56] [height=55.00]
+          LayoutSVGText {text} at (103,216) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (103.35,223.00) startOffset 0 endOffset 1 width 4.00: "6"
+          LayoutSVGRect {rect} at (119,169) size 14x55 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=111.63] [y=161.00] [width=12.56] [height=55.00]
+          LayoutSVGText {text} at (115,216) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (115.91,223.00) startOffset 0 endOffset 1 width 4.00: "7"
+          LayoutSVGRect {rect} at (132,169) size 13x55 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=124.19] [y=161.00] [width=12.56] [height=55.00]
+          LayoutSVGText {text} at (128,216) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (128.47,223.00) startOffset 0 endOffset 1 width 4.00: "8"
+          LayoutSVGRect {rect} at (208,177) size 12x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=200.00] [y=169.00] [width=11.66] [height=40.00]
+          LayoutSVGText {text} at (203,209) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (203.83,216.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (219,177) size 6x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=211.66] [y=169.00] [width=4.86] [height=40.00]
+          LayoutSVGText {text} at (212,209) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (212.09,216.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (224,177) size 6x40 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=216.52] [y=169.00] [width=4.86] [height=40.00]
+          LayoutSVGText {text} at (216,209) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (216.95,216.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (229,177) size 10x40 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=221.38] [y=169.00] [width=8.75] [height=40.00]
+          LayoutSVGText {text} at (223,209) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (223.75,216.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (238,177) size 12x40 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=230.13] [y=169.00] [width=11.04] [height=40.00]
+          LayoutSVGText {text} at (233,209) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (233.65,216.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (249,177) size 13x40 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=241.17] [y=169.00] [width=12.30] [height=40.00]
+          LayoutSVGText {text} at (245,209) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (245.32,216.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (261,177) size 4x40 [fill={[type=SOLID] [color=#EE82EE] [opacity=0.30]}] [x=253.47] [y=169.00] [width=3.24] [height=40.00]
+          LayoutSVGText {text} at (253,209) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (253.09,216.00) startOffset 0 endOffset 1 width 4.00: "6"
+          LayoutSVGRect {rect} at (264,177) size 4x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=256.72] [y=169.00] [width=3.24] [height=40.00]
+          LayoutSVGText {text} at (256,209) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (256.34,216.00) startOffset 0 endOffset 1 width 4.00: "7"
+          LayoutSVGRect {rect} at (267,177) size 5x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=259.96] [y=169.00] [width=3.24] [height=40.00]
+          LayoutSVGText {text} at (259,209) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (259.58,216.00) startOffset 0 endOffset 1 width 4.00: "8"
+          LayoutSVGRect {rect} at (358,176) size 6x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=350.00] [y=168.00] [width=5.85] [height=40.00]
+          LayoutSVGText {text} at (350,208) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (350.93,215.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (363,176) size 7x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=355.85] [y=168.00] [width=5.85] [height=40.00]
+          LayoutSVGText {text} at (356,208) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (356.78,215.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (369,176) size 7x40 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=361.71] [y=168.00] [width=5.85] [height=40.00]
+          LayoutSVGText {text} at (362,208) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (362.63,215.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (375,176) size 11x40 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=367.56] [y=168.00] [width=9.72] [height=40.00]
+          LayoutSVGText {text} at (370,208) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (370.42,215.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (385,176) size 11x40 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=377.28] [y=168.00] [width=9.72] [height=40.00]
+          LayoutSVGText {text} at (380,208) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (380.15,215.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (395,176) size 5x40 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=387.01] [y=168.00] [width=4.39] [height=40.00]
+          LayoutSVGText {text} at (387,208) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (387.20,215.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (399,176) size 5x40 [fill={[type=SOLID] [color=#EE82EE] [opacity=0.30]}] [x=391.40] [y=168.00] [width=4.39] [height=40.00]
+          LayoutSVGText {text} at (391,208) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (391.59,215.00) startOffset 0 endOffset 1 width 4.00: "6"
+          LayoutSVGRect {rect} at (403,176) size 6x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=395.79] [y=168.00] [width=4.39] [height=40.00]
+          LayoutSVGText {text} at (395,208) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (395.98,215.00) startOffset 0 endOffset 1 width 4.00: "7"
+          LayoutSVGRect {rect} at (408,176) size 5x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=400.18] [y=168.00] [width=4.39] [height=40.00]
+          LayoutSVGText {text} at (400,208) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (400.37,215.00) startOffset 0 endOffset 1 width 4.00: "8"
+          LayoutSVGRect {rect} at (58,244) size 2x55 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=50.00] [y=236.00] [width=1.45] [height=55.00]
+          LayoutSVGText {text} at (48,291) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (48.73,298.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (59,244) size 16x55 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=51.45] [y=236.00] [width=15.24] [height=55.00]
+          LayoutSVGText {text} at (57,291) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (57.07,298.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (74,244) size 16x55 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=66.69] [y=236.00] [width=15.24] [height=55.00]
+          LayoutSVGText {text} at (72,291) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (72.31,298.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (117,244) size 8x55 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=109.47] [y=236.00] [width=7.10] [height=55.00]
+          LayoutSVGText {text} at (111,291) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (111.02,298.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (110,244) size 8x55 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=102.37] [y=236.00] [width=7.10] [height=55.00]
+          LayoutSVGText {text} at (103,291) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (103.92,298.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (100,244) size 11x55 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=92.15] [y=236.00] [width=10.22] [height=55.00]
+          LayoutSVGText {text} at (95,291) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (95.26,298.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (89,244) size 12x55 [fill={[type=SOLID] [color=#EE82EE] [opacity=0.30]}] [x=81.92] [y=236.00] [width=10.22] [height=55.00]
+          LayoutSVGText {text} at (85,291) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (85.03,298.00) startOffset 0 endOffset 1 width 4.00: "6"
+          LayoutSVGRect {rect} at (124,244) size 3x55 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=116.58] [y=236.00] [width=1.45] [height=55.00]
+          LayoutSVGText {text} at (115,291) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (115.30,298.00) startOffset 0 endOffset 1 width 4.00: "7"
+          LayoutSVGRect {rect} at (126,244) size 16x55 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=118.03] [y=236.00] [width=15.24] [height=55.00]
+          LayoutSVGText {text} at (123,291) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (123.65,298.00) startOffset 0 endOffset 1 width 4.00: "8"
+          LayoutSVGRect {rect} at (141,244) size 16x55 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=133.26] [y=236.00] [width=15.24] [height=55.00]
+          LayoutSVGText {text} at (138,291) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (138.88,298.00) startOffset 0 endOffset 1 width 4.00: "9"
+          LayoutSVGRect {rect} at (208,252) size 12x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=200.00] [y=244.00] [width=11.04] [height=40.00]
+          LayoutSVGText {text} at (203,284) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (203.52,291.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (219,252) size 6x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=211.04] [y=244.00] [width=5.83] [height=40.00]
+          LayoutSVGText {text} at (211,284) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (211.95,291.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (224,252) size 7x40 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=216.87] [y=244.00] [width=5.83] [height=40.00]
+          LayoutSVGText {text} at (217,284) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (217.78,291.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (258,252) size 8x40 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=250.24] [y=244.00] [width=7.10] [height=40.00]
+          LayoutSVGText {text} at (251,284) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (251.79,291.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (251,252) size 8x40 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=243.14] [y=244.00] [width=7.10] [height=40.00]
+          LayoutSVGText {text} at (244,284) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (244.69,291.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (240,252) size 12x40 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=232.92] [y=244.00] [width=10.22] [height=40.00]
+          LayoutSVGText {text} at (236,284) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (236.03,291.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (230,252) size 11x40 [fill={[type=SOLID] [color=#EE82EE] [opacity=0.30]}] [x=222.70] [y=244.00] [width=10.22] [height=40.00]
+          LayoutSVGText {text} at (225,284) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (225.81,291.00) startOffset 0 endOffset 1 width 4.00: "6"
+          LayoutSVGRect {rect} at (265,252) size 12x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=257.35] [y=244.00] [width=11.04] [height=40.00]
+          LayoutSVGText {text} at (260,284) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (260.87,291.00) startOffset 0 endOffset 1 width 4.00: "7"
+          LayoutSVGRect {rect} at (276,252) size 7x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=268.39] [y=244.00] [width=5.83] [height=40.00]
+          LayoutSVGText {text} at (269,284) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (269.30,291.00) startOffset 0 endOffset 1 width 4.00: "8"
+          LayoutSVGRect {rect} at (282,252) size 7x40 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=274.21] [y=244.00] [width=5.83] [height=40.00]
+          LayoutSVGText {text} at (275,284) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (275.13,291.00) startOffset 0 endOffset 1 width 4.00: "9"
+          LayoutSVGRect {rect} at (358,251) size 10x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=350.00] [y=243.00] [width=9.40] [height=40.00]
+          LayoutSVGText {text} at (352,283) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (352.70,290.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (367,251) size 8x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=359.40] [y=243.00] [width=7.27] [height=40.00]
+          LayoutSVGText {text} at (361,283) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (361.04,290.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (374,251) size 8x40 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=366.67] [y=243.00] [width=7.27] [height=40.00]
+          LayoutSVGText {text} at (368,283) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (368.31,290.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (409,251) size 8x40 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=401.49] [y=243.00] [width=7.10] [height=40.00]
+          LayoutSVGText {text} at (403,283) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (403.04,290.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (402,251) size 8x40 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=394.39] [y=243.00] [width=7.10] [height=40.00]
+          LayoutSVGText {text} at (395,283) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (395.94,290.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (392,251) size 11x40 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=384.16] [y=243.00] [width=10.22] [height=40.00]
+          LayoutSVGText {text} at (387,283) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (387.28,290.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (381,251) size 12x40 [fill={[type=SOLID] [color=#EE82EE] [opacity=0.30]}] [x=373.94] [y=243.00] [width=10.22] [height=40.00]
+          LayoutSVGText {text} at (377,283) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (377.05,290.00) startOffset 0 endOffset 1 width 4.00: "6"
+          LayoutSVGRect {rect} at (416,251) size 10x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=408.59] [y=243.00] [width=9.40] [height=40.00]
+          LayoutSVGText {text} at (411,283) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (411.29,290.00) startOffset 0 endOffset 1 width 4.00: "7"
+          LayoutSVGRect {rect} at (425,251) size 9x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=417.99] [y=243.00] [width=7.27] [height=40.00]
+          LayoutSVGText {text} at (419,283) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (419.63,290.00) startOffset 0 endOffset 1 width 4.00: "8"
+          LayoutSVGRect {rect} at (433,251) size 8x40 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=425.27] [y=243.00] [width=7.27] [height=40.00]
+          LayoutSVGText {text} at (426,283) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (426.90,290.00) startOffset 0 endOffset 1 width 4.00: "9"
+          LayoutSVGRect {rect} at (58,319) size 16x55 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=50.00] [y=311.00] [width=15.62] [height=55.00]
+          LayoutSVGText {text} at (55,366) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (55.81,373.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (73,319) size 50x55 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=65.62] [y=311.00] [width=49.07] [height=55.00]
+          LayoutSVGText {text} at (88,366) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (88.15,373.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (122,319) size 26x55 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=114.69] [y=311.00] [width=25.28] [height=55.00]
+          LayoutSVGText {text} at (125,366) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (125.32,373.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (147,319) size 27x55 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=139.96] [y=311.00] [width=25.28] [height=55.00]
+          LayoutSVGText {text} at (150,366) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (150.60,373.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (208,327) size 13x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=200.00] [y=319.00] [width=12.24] [height=40.00]
+          LayoutSVGText {text} at (204,359) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (204.12,366.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (220,327) size 50x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=212.24] [y=319.00] [width=49.07] [height=40.00]
+          LayoutSVGText {text} at (234,359) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (234.77,366.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (269,327) size 12x40 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=261.30] [y=319.00] [width=10.75] [height=40.00]
+          LayoutSVGText {text} at (264,359) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (264.68,366.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (280,327) size 11x40 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=272.05] [y=319.00] [width=10.75] [height=40.00]
+          LayoutSVGText {text} at (275,359) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (275.43,366.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (358,326) size 15x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=350.00] [y=318.00] [width=14.83] [height=40.00]
+          LayoutSVGText {text} at (355,358) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (355.42,365.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (372,326) size 50x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=364.83] [y=318.00] [width=49.07] [height=40.00]
+          LayoutSVGText {text} at (387,358) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (387.37,365.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (421,326) size 9x40 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=413.90] [y=318.00] [width=7.88] [height=40.00]
+          LayoutSVGText {text} at (415,358) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (415.84,365.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (429,326) size 9x40 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=421.78] [y=318.00] [width=7.88] [height=40.00]
+          LayoutSVGText {text} at (423,358) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (423.72,365.00) startOffset 0 endOffset 1 width 4.00: "3"
+        LayoutSVGContainer {g} at (50,18) size 391x357
+          LayoutSVGText {text} at (50,10) size 50x56 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 50x56
+              chunk 1 text run 1 at (50.00,50.00) startOffset 0 endOffset 6 width 48.33: "ab\x{30C}c\x{30C}\x{30C}"
+          LayoutSVGText {text} at (200,15) size 49x44 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 49x44
+              chunk 1 text run 1 at (200.00,50.00) startOffset 0 endOffset 6 width 48.57: "ab\x{30C}c\x{30C}\x{30C}"
+          LayoutSVGText {text} at (350,16) size 58x42 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 58x42
+              chunk 1 text run 1 at (350.00,50.00) startOffset 0 endOffset 6 width 57.51: "ab\x{30C}c\x{30C}\x{30C}"
+          LayoutSVGText {text} at (51,86) size 50x55 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 49x55
+              chunk 1 text run 1 at (51.67,125.00) startOffset 0 endOffset 3 width 13.40: "c\x{30C}\x{30C}"
+              chunk 1 text run 1 at (65.07,125.00) startOffset 0 endOffset 1 width 0.00 RTL: "\x{200F}"
+              chunk 1 text run 1 at (65.07,125.00) startOffset 0 endOffset 2 width 16.97: "b\x{30C}"
+              chunk 1 text run 1 at (82.04,125.00) startOffset 0 endOffset 1 width 0.00 RTL: "\x{200F}"
+              chunk 1 text run 1 at (82.04,125.00) startOffset 0 endOffset 1 width 17.96: "a"
+              chunk 1 text run 1 at (100.00,125.00) startOffset 0 endOffset 1 width 0.00 RTL: "\x{200F}"
+          LayoutSVGText {text} at (201,94) size 49x40 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 49x40
+              chunk 1 text run 1 at (201.43,125.00) startOffset 0 endOffset 3 width 15.53: "c\x{30C}\x{30C}"
+              chunk 1 text run 1 at (216.97,125.00) startOffset 0 endOffset 1 width 0.00 RTL: "\x{200F}"
+              chunk 1 text run 1 at (216.97,125.00) startOffset 0 endOffset 2 width 17.50: "b\x{30C}"
+              chunk 1 text run 1 at (234.47,125.00) startOffset 0 endOffset 1 width 0.00 RTL: "\x{200F}"
+              chunk 1 text run 1 at (234.47,125.00) startOffset 0 endOffset 1 width 15.53: "a"
+              chunk 1 text run 1 at (250.00,125.00) startOffset 0 endOffset 1 width 0.00 RTL: "\x{200F}"
+          LayoutSVGText {text} at (342,93) size 58x40 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 58x40
+              chunk 1 text run 1 at (342.15,125.00) startOffset 0 endOffset 3 width 18.58: "c\x{30C}\x{30C}"
+              chunk 1 text run 1 at (360.73,125.00) startOffset 0 endOffset 1 width 0.00 RTL: "\x{200F}"
+              chunk 1 text run 1 at (360.73,125.00) startOffset 0 endOffset 2 width 19.81: "b\x{30C}"
+              chunk 1 text run 1 at (380.53,125.00) startOffset 0 endOffset 1 width 0.00 RTL: "\x{200F}"
+              chunk 1 text run 1 at (380.53,125.00) startOffset 0 endOffset 1 width 19.47: "a"
+              chunk 1 text run 1 at (400.00,125.00) startOffset 0 endOffset 1 width 0.00 RTL: "\x{200F}"
+          LayoutSVGText {text} at (42,160) size 95x56 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 95x56
+              chunk 1 text run 1 at (50.00,200.00) startOffset 0 endOffset 9 width 86.75: "fi\x{30C} ffi\x{30C}\x{30C}"
+          LayoutSVGText {text} at (200,169) size 64x40 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 64x40
+              chunk 1 text run 1 at (200.00,200.00) startOffset 0 endOffset 9 width 63.20: "fi\x{30C} ffi\x{30C}\x{30C}"
+          LayoutSVGText {text} at (350,166) size 55x42 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 55x42
+              chunk 1 text run 1 at (350.00,200.00) startOffset 0 endOffset 9 width 54.57: "fi\x{30C} ffi\x{30C}\x{30C}"
+          LayoutSVGText {text} at (42,236) size 107x55 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 107x55
+              chunk 1 text run 1 at (50.00,275.00) startOffset 0 endOffset 3 width 31.92: "ff\x{30C}"
+              chunk 1 text run 1 at (81.92,275.00) startOffset 0 endOffset 4 width 34.65 RTL: "\x{640}\x{640}\x{644}\x{627}"
+              chunk 1 text run 1 at (116.58,275.00) startOffset 0 endOffset 3 width 31.92: "ff\x{30C}"
+          LayoutSVGText {text} at (200,244) size 82x40 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 82x40
+              chunk 1 text run 1 at (200.00,275.00) startOffset 0 endOffset 3 width 22.70: "ff\x{30C}"
+              chunk 1 text run 1 at (222.70,275.00) startOffset 0 endOffset 4 width 34.65 RTL: "\x{640}\x{640}\x{644}\x{627}"
+              chunk 1 text run 1 at (257.35,275.00) startOffset 0 endOffset 3 width 22.70: "ff\x{30C}"
+          LayoutSVGText {text} at (350,243) size 83x40 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 83x40
+              chunk 1 text run 1 at (350.00,275.00) startOffset 0 endOffset 3 width 23.94: "ff\x{30C}"
+              chunk 1 text run 1 at (373.94,275.00) startOffset 0 endOffset 4 width 34.65 RTL: "\x{640}\x{640}\x{644}\x{627}"
+              chunk 1 text run 1 at (408.59,275.00) startOffset 0 endOffset 3 width 23.94: "ff\x{30C}"
+          LayoutSVGText {text} at (50,311) size 116x56 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 116x56
+              chunk 1 text run 1 at (50.00,350.00) startOffset 0 endOffset 1 width 15.62: "\x{30C}"
+              chunk 1 text run 1 at (65.62,350.00) startOffset 0 endOffset 1 width 49.07 RTL: "\x{FDB0}"
+              chunk 1 text run 1 at (114.69,350.00) startOffset 0 endOffset 2 width 50.55: "i\x{333}"
+          LayoutSVGText {text} at (199,319) size 84x48 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 84x48
+              chunk 1 text run 1 at (200.00,350.00) startOffset 0 endOffset 1 width 12.24: "\x{30C}"
+              chunk 1 text run 1 at (212.24,350.00) startOffset 0 endOffset 1 width 49.07 RTL: "\x{FDB0}"
+              chunk 1 text run 1 at (261.30,350.00) startOffset 0 endOffset 2 width 21.50: "i\x{333}"
+          LayoutSVGText {text} at (335,318) size 95x49 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 95x49
+              chunk 1 text run 1 at (350.00,350.00) startOffset 0 endOffset 1 width 14.83: "\x{30C}"
+              chunk 1 text run 1 at (364.83,350.00) startOffset 0 endOffset 1 width 49.07 RTL: "\x{FDB0}"
+              chunk 1 text run 1 at (413.90,350.00) startOffset 0 endOffset 2 width 15.76: "i\x{333}"
+      LayoutText {#text} at (0,0) size 0x0
+      LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/svg/text/combining-character-queries-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/svg/text/combining-character-queries-expected.png
new file mode 100644
index 0000000..a141403
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/svg/text/combining-character-queries-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/svg/text/combining-character-queries-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/svg/text/combining-character-queries-expected.txt
new file mode 100644
index 0000000..05d135a1
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/svg/text/combining-character-queries-expected.txt
@@ -0,0 +1,538 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x520
+  LayoutBlockFlow {HTML} at (0,0) size 800x520
+    LayoutBlockFlow {BODY} at (8,8) size 784x504
+      LayoutSVGRoot {svg} at (50,18) size 382x365
+        LayoutSVGContainer {g} at (56,19) size 375x364
+          LayoutSVGRect {rect} at (58,19) size 18x55 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=50.00] [y=11.00] [width=17.96] [height=55.00]
+          LayoutSVGText {text} at (56,66) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (56.98,73.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (75,19) size 10x55 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=67.96] [y=11.00] [width=8.49] [height=55.00]
+          LayoutSVGText {text} at (70,66) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (70.20,73.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (84,19) size 9x55 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=76.45] [y=11.00] [width=8.49] [height=55.00]
+          LayoutSVGText {text} at (78,66) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (78.69,73.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (92,19) size 6x55 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=84.93] [y=11.00] [width=4.47] [height=55.00]
+          LayoutSVGText {text} at (85,66) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (85.16,73.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (97,19) size 5x55 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=89.40] [y=11.00] [width=4.47] [height=55.00]
+          LayoutSVGText {text} at (89,66) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (89.63,73.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (101,19) size 6x55 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=93.86] [y=11.00] [width=4.47] [height=55.00]
+          LayoutSVGText {text} at (94,66) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (94.10,73.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (208,27) size 16x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=200.00] [y=19.00] [width=15.53] [height=40.00]
+          LayoutSVGText {text} at (205,59) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (205.77,66.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (223,27) size 10x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=215.53] [y=19.00] [width=8.75] [height=40.00]
+          LayoutSVGText {text} at (217,59) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (217.91,66.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (232,27) size 10x40 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=224.28] [y=19.00] [width=8.75] [height=40.00]
+          LayoutSVGText {text} at (226,59) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (226.66,66.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (241,27) size 6x40 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=233.03] [y=19.00] [width=5.18] [height=40.00]
+          LayoutSVGText {text} at (233,59) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (233.62,66.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (246,27) size 6x40 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=238.21] [y=19.00] [width=5.18] [height=40.00]
+          LayoutSVGText {text} at (238,59) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (238.80,66.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (251,27) size 6x40 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=243.39] [y=19.00] [width=5.18] [height=40.00]
+          LayoutSVGText {text} at (243,59) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (243.98,66.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (358,26) size 20x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=350.00] [y=18.00] [width=19.47] [height=40.00]
+          LayoutSVGText {text} at (357,58) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (357.73,65.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (377,26) size 11x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=369.47] [y=18.00] [width=9.73] [height=40.00]
+          LayoutSVGText {text} at (372,58) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (372.33,65.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (387,26) size 10x40 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=379.20] [y=18.00] [width=9.73] [height=40.00]
+          LayoutSVGText {text} at (382,58) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (382.06,65.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (396,26) size 7x40 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=388.93] [y=18.00] [width=5.83] [height=40.00]
+          LayoutSVGText {text} at (389,58) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (389.85,65.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (402,26) size 7x40 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=394.76] [y=18.00] [width=5.83] [height=40.00]
+          LayoutSVGText {text} at (395,58) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (395.68,65.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (408,26) size 7x40 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=400.60] [y=18.00] [width=5.83] [height=40.00]
+          LayoutSVGText {text} at (401,58) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (401.51,65.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (8,8) size 0x0 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=100.00] [y=86.00] [width=0.00] [height=55.00]
+          LayoutSVGText {text} at (97,141) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (98.00,148.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (90,94) size 18x55 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=82.04] [y=86.00] [width=17.96] [height=55.00]
+          LayoutSVGText {text} at (89,141) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (89.02,148.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (8,8) size 0x0 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=82.04] [y=86.00] [width=0.00] [height=55.00]
+          LayoutSVGText {text} at (80,141) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (80.04,148.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (73,94) size 9x55 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=65.07] [y=86.00] [width=8.49] [height=55.00]
+          LayoutSVGText {text} at (67,141) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (67.31,148.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (81,94) size 10x55 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=73.55] [y=86.00] [width=8.49] [height=55.00]
+          LayoutSVGText {text} at (75,141) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (75.80,148.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (8,8) size 0x0 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=65.07] [y=86.00] [width=0.00] [height=55.00]
+          LayoutSVGText {text} at (63,141) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (63.07,148.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (59,94) size 6x55 [fill={[type=SOLID] [color=#EE82EE] [opacity=0.30]}] [x=51.67] [y=86.00] [width=4.47] [height=55.00]
+          LayoutSVGText {text} at (51,141) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (51.90,148.00) startOffset 0 endOffset 1 width 4.00: "6"
+          LayoutSVGRect {rect} at (64,94) size 5x55 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=56.14] [y=86.00] [width=4.47] [height=55.00]
+          LayoutSVGText {text} at (56,141) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (56.37,148.00) startOffset 0 endOffset 1 width 4.00: "7"
+          LayoutSVGRect {rect} at (68,94) size 6x55 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=60.60] [y=86.00] [width=4.47] [height=55.00]
+          LayoutSVGText {text} at (60,141) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (60.84,148.00) startOffset 0 endOffset 1 width 4.00: "8"
+          LayoutSVGRect {rect} at (8,8) size 0x0 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=250.00] [y=94.00] [width=0.00] [height=40.00]
+          LayoutSVGText {text} at (248,134) size 4x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (248.00,141.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (242,102) size 16x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=234.47] [y=94.00] [width=15.53] [height=40.00]
+          LayoutSVGText {text} at (240,134) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (240.23,141.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (8,8) size 0x0 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=234.47] [y=94.00] [width=0.00] [height=40.00]
+          LayoutSVGText {text} at (232,134) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (232.47,141.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (224,102) size 10x40 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=216.97] [y=94.00] [width=8.75] [height=40.00]
+          LayoutSVGText {text} at (219,134) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (219.34,141.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (233,102) size 10x40 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=225.72] [y=94.00] [width=8.75] [height=40.00]
+          LayoutSVGText {text} at (228,134) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (228.09,141.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (8,8) size 0x0 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=216.97] [y=94.00] [width=0.00] [height=40.00]
+          LayoutSVGText {text} at (214,134) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (214.97,141.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (209,102) size 6x40 [fill={[type=SOLID] [color=#EE82EE] [opacity=0.30]}] [x=201.43] [y=94.00] [width=5.18] [height=40.00]
+          LayoutSVGText {text} at (202,134) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (202.02,141.00) startOffset 0 endOffset 1 width 4.00: "6"
+          LayoutSVGRect {rect} at (214,102) size 6x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=206.61] [y=94.00] [width=5.18] [height=40.00]
+          LayoutSVGText {text} at (207,134) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (207.20,141.00) startOffset 0 endOffset 1 width 4.00: "7"
+          LayoutSVGRect {rect} at (219,102) size 6x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=211.79] [y=94.00] [width=5.18] [height=40.00]
+          LayoutSVGText {text} at (212,134) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (212.38,141.00) startOffset 0 endOffset 1 width 4.00: "8"
+          LayoutSVGRect {rect} at (8,8) size 0x0 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=400.00] [y=93.00] [width=0.00] [height=40.00]
+          LayoutSVGText {text} at (398,133) size 4x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (398.00,140.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (388,101) size 20x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=380.53] [y=93.00] [width=19.47] [height=40.00]
+          LayoutSVGText {text} at (388,133) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (388.27,140.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (8,8) size 0x0 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=380.53] [y=93.00] [width=0.00] [height=40.00]
+          LayoutSVGText {text} at (378,133) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (378.53,140.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (369,101) size 10x40 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=361.07] [y=93.00] [width=9.73] [height=40.00]
+          LayoutSVGText {text} at (363,133) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (363.94,140.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (378,101) size 11x40 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=370.80] [y=93.00] [width=9.73] [height=40.00]
+          LayoutSVGText {text} at (373,133) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (373.67,140.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (8,8) size 0x0 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=361.07] [y=93.00] [width=0.00] [height=40.00]
+          LayoutSVGText {text} at (359,133) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (359.07,140.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (351,101) size 7x40 [fill={[type=SOLID] [color=#EE82EE] [opacity=0.30]}] [x=343.57] [y=93.00] [width=5.83] [height=40.00]
+          LayoutSVGText {text} at (344,133) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (344.49,140.00) startOffset 0 endOffset 1 width 4.00: "6"
+          LayoutSVGRect {rect} at (357,101) size 7x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=349.40] [y=93.00] [width=5.83] [height=40.00]
+          LayoutSVGText {text} at (350,133) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (350.32,140.00) startOffset 0 endOffset 1 width 4.00: "7"
+          LayoutSVGRect {rect} at (363,101) size 7x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=355.24] [y=93.00] [width=5.83] [height=40.00]
+          LayoutSVGText {text} at (356,133) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (356.15,140.00) startOffset 0 endOffset 1 width 4.00: "8"
+          LayoutSVGRect {rect} at (58,169) size 6x55 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=50.00] [y=161.00] [width=5.97] [height=55.00]
+          LayoutSVGText {text} at (50,216) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (50.99,223.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (63,169) size 14x55 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=55.97] [y=161.00] [width=12.36] [height=55.00]
+          LayoutSVGText {text} at (60,216) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (60.15,223.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (76,169) size 13x55 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=68.33] [y=161.00] [width=12.36] [height=55.00]
+          LayoutSVGText {text} at (72,216) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (72.51,223.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (88,169) size 11x55 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=80.69] [y=161.00] [width=9.72] [height=55.00]
+          LayoutSVGText {text} at (83,216) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (83.56,223.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (98,169) size 1x55 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=90.42] [y=161.00] [width=0.42] [height=55.00]
+          LayoutSVGText {text} at (88,216) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (88.63,223.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (98,169) size 2x55 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=90.84] [y=161.00] [width=0.42] [height=55.00]
+          LayoutSVGText {text} at (89,216) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (89.05,223.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (99,169) size 11x55 [fill={[type=SOLID] [color=#EE82EE] [opacity=0.30]}] [x=91.25] [y=161.00] [width=9.96] [height=55.00]
+          LayoutSVGText {text} at (94,216) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (94.23,223.00) startOffset 0 endOffset 1 width 4.00: "6"
+          LayoutSVGRect {rect} at (109,169) size 11x55 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=101.21] [y=161.00] [width=9.96] [height=55.00]
+          LayoutSVGText {text} at (104,216) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (104.19,223.00) startOffset 0 endOffset 1 width 4.00: "7"
+          LayoutSVGRect {rect} at (119,169) size 11x55 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=111.17] [y=161.00] [width=9.96] [height=55.00]
+          LayoutSVGText {text} at (114,216) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (114.15,223.00) startOffset 0 endOffset 1 width 4.00: "8"
+          LayoutSVGRect {rect} at (208,177) size 12x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=200.00] [y=169.00] [width=11.66] [height=40.00]
+          LayoutSVGText {text} at (203,209) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (203.83,216.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (219,177) size 6x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=211.66] [y=169.00] [width=4.86] [height=40.00]
+          LayoutSVGText {text} at (212,209) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (212.09,216.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (224,177) size 6x40 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=216.52] [y=169.00] [width=4.86] [height=40.00]
+          LayoutSVGText {text} at (216,209) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (216.95,216.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (229,177) size 10x40 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=221.38] [y=169.00] [width=8.75] [height=40.00]
+          LayoutSVGText {text} at (223,209) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (223.75,216.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (238,177) size 12x40 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=230.13] [y=169.00] [width=11.04] [height=40.00]
+          LayoutSVGText {text} at (233,209) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (233.65,216.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (249,177) size 13x40 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=241.17] [y=169.00] [width=12.30] [height=40.00]
+          LayoutSVGText {text} at (245,209) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (245.32,216.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (261,177) size 4x40 [fill={[type=SOLID] [color=#EE82EE] [opacity=0.30]}] [x=253.47] [y=169.00] [width=3.24] [height=40.00]
+          LayoutSVGText {text} at (253,209) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (253.09,216.00) startOffset 0 endOffset 1 width 4.00: "6"
+          LayoutSVGRect {rect} at (264,177) size 4x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=256.72] [y=169.00] [width=3.24] [height=40.00]
+          LayoutSVGText {text} at (256,209) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (256.34,216.00) startOffset 0 endOffset 1 width 4.00: "7"
+          LayoutSVGRect {rect} at (267,177) size 5x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=259.96] [y=169.00] [width=3.24] [height=40.00]
+          LayoutSVGText {text} at (259,209) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (259.58,216.00) startOffset 0 endOffset 1 width 4.00: "8"
+          LayoutSVGRect {rect} at (358,176) size 18x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=350.00] [y=168.00] [width=17.56] [height=40.00]
+          LayoutSVGText {text} at (356,208) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (356.78,215.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (375,176) size 1x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=367.56] [y=168.00] [width=0.03] [height=40.00]
+          LayoutSVGText {text} at (365,208) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (365.57,215.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (375,176) size 1x40 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=367.59] [y=168.00] [width=0.03] [height=40.00]
+          LayoutSVGText {text} at (365,208) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (365.60,215.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (375,176) size 11x40 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=367.62] [y=168.00] [width=9.72] [height=40.00]
+          LayoutSVGText {text} at (370,208) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (370.48,215.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (385,176) size 11x40 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=377.34] [y=168.00] [width=9.72] [height=40.00]
+          LayoutSVGText {text} at (380,208) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (380.21,215.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (395,176) size 18x40 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=387.07] [y=168.00] [width=17.56] [height=40.00]
+          LayoutSVGText {text} at (393,208) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (393.85,215.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (412,176) size 1x40 [fill={[type=SOLID] [color=#EE82EE] [opacity=0.30]}] [x=404.63] [y=168.00] [width=0.02] [height=40.00]
+          LayoutSVGText {text} at (402,208) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (402.64,215.00) startOffset 0 endOffset 1 width 4.00: "6"
+          LayoutSVGRect {rect} at (412,176) size 1x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=404.65] [y=168.00] [width=0.02] [height=40.00]
+          LayoutSVGText {text} at (402,208) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (402.66,215.00) startOffset 0 endOffset 1 width 4.00: "7"
+          LayoutSVGRect {rect} at (412,176) size 1x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=404.67] [y=168.00] [width=0.02] [height=40.00]
+          LayoutSVGText {text} at (402,208) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (402.68,215.00) startOffset 0 endOffset 1 width 4.00: "8"
+          LayoutSVGRect {rect} at (58,244) size 2x55 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=50.00] [y=236.00] [width=1.45] [height=55.00]
+          LayoutSVGText {text} at (48,291) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (48.73,298.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (59,244) size 12x55 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=51.45] [y=236.00] [width=11.33] [height=55.00]
+          LayoutSVGText {text} at (55,291) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (55.12,298.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (70,244) size 13x55 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=62.78] [y=236.00] [width=11.33] [height=55.00]
+          LayoutSVGText {text} at (66,291) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (66.45,298.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (109,244) size 8x55 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=101.66] [y=236.00] [width=7.10] [height=55.00]
+          LayoutSVGText {text} at (103,291) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (103.21,298.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (102,244) size 8x55 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=94.56] [y=236.00] [width=7.10] [height=55.00]
+          LayoutSVGText {text} at (96,291) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (96.11,298.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (92,244) size 11x55 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=84.34] [y=236.00] [width=10.22] [height=55.00]
+          LayoutSVGText {text} at (87,291) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (87.45,298.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (82,244) size 11x55 [fill={[type=SOLID] [color=#EE82EE] [opacity=0.30]}] [x=74.11] [y=236.00] [width=10.22] [height=55.00]
+          LayoutSVGText {text} at (77,291) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (77.22,298.00) startOffset 0 endOffset 1 width 4.00: "6"
+          LayoutSVGRect {rect} at (116,244) size 3x55 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=108.77] [y=236.00] [width=1.45] [height=55.00]
+          LayoutSVGText {text} at (107,291) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (107.49,298.00) startOffset 0 endOffset 1 width 4.00: "7"
+          LayoutSVGRect {rect} at (118,244) size 12x55 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=110.22] [y=236.00] [width=11.33] [height=55.00]
+          LayoutSVGText {text} at (113,291) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (113.88,298.00) startOffset 0 endOffset 1 width 4.00: "8"
+          LayoutSVGRect {rect} at (129,244) size 12x55 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=121.55] [y=236.00] [width=11.33] [height=55.00]
+          LayoutSVGText {text} at (125,291) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (125.21,298.00) startOffset 0 endOffset 1 width 4.00: "9"
+          LayoutSVGRect {rect} at (208,252) size 12x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=200.00] [y=244.00] [width=11.04] [height=40.00]
+          LayoutSVGText {text} at (203,284) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (203.52,291.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (219,252) size 6x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=211.04] [y=244.00] [width=5.83] [height=40.00]
+          LayoutSVGText {text} at (211,284) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (211.95,291.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (224,252) size 7x40 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=216.87] [y=244.00] [width=5.83] [height=40.00]
+          LayoutSVGText {text} at (217,284) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (217.78,291.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (258,252) size 8x40 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=250.24] [y=244.00] [width=7.10] [height=40.00]
+          LayoutSVGText {text} at (251,284) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (251.79,291.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (251,252) size 8x40 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=243.14] [y=244.00] [width=7.10] [height=40.00]
+          LayoutSVGText {text} at (244,284) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (244.69,291.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (240,252) size 12x40 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=232.92] [y=244.00] [width=10.22] [height=40.00]
+          LayoutSVGText {text} at (236,284) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (236.03,291.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (230,252) size 11x40 [fill={[type=SOLID] [color=#EE82EE] [opacity=0.30]}] [x=222.70] [y=244.00] [width=10.22] [height=40.00]
+          LayoutSVGText {text} at (225,284) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (225.81,291.00) startOffset 0 endOffset 1 width 4.00: "6"
+          LayoutSVGRect {rect} at (265,252) size 12x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=257.35] [y=244.00] [width=11.04] [height=40.00]
+          LayoutSVGText {text} at (260,284) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (260.87,291.00) startOffset 0 endOffset 1 width 4.00: "7"
+          LayoutSVGRect {rect} at (276,252) size 7x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=268.39] [y=244.00] [width=5.83] [height=40.00]
+          LayoutSVGText {text} at (269,284) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (269.30,291.00) startOffset 0 endOffset 1 width 4.00: "8"
+          LayoutSVGRect {rect} at (282,252) size 7x40 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=274.21] [y=244.00] [width=5.83] [height=40.00]
+          LayoutSVGText {text} at (275,284) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (275.13,291.00) startOffset 0 endOffset 1 width 4.00: "9"
+          LayoutSVGRect {rect} at (358,251) size 10x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=350.00] [y=243.00] [width=9.40] [height=40.00]
+          LayoutSVGText {text} at (352,283) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (352.70,290.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (367,251) size 6x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=359.40] [y=243.00] [width=4.86] [height=40.00]
+          LayoutSVGText {text} at (359,283) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (359.83,290.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (372,251) size 6x40 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=364.26] [y=243.00] [width=4.86] [height=40.00]
+          LayoutSVGText {text} at (364,283) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (364.69,290.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (404,251) size 8x40 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=396.67] [y=243.00] [width=7.10] [height=40.00]
+          LayoutSVGText {text} at (398,283) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (398.22,290.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (397,251) size 8x40 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=389.57] [y=243.00] [width=7.10] [height=40.00]
+          LayoutSVGText {text} at (391,283) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (391.12,290.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (387,251) size 11x40 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=379.35] [y=243.00] [width=10.22] [height=40.00]
+          LayoutSVGText {text} at (382,283) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (382.46,290.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (377,251) size 11x40 [fill={[type=SOLID] [color=#EE82EE] [opacity=0.30]}] [x=369.12] [y=243.00] [width=10.22] [height=40.00]
+          LayoutSVGText {text} at (372,283) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (372.23,290.00) startOffset 0 endOffset 1 width 4.00: "6"
+          LayoutSVGRect {rect} at (411,251) size 11x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=403.78] [y=243.00] [width=9.40] [height=40.00]
+          LayoutSVGText {text} at (406,283) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (406.48,290.00) startOffset 0 endOffset 1 width 4.00: "7"
+          LayoutSVGRect {rect} at (421,251) size 6x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=413.17] [y=243.00] [width=4.86] [height=40.00]
+          LayoutSVGText {text} at (413,283) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (413.61,290.00) startOffset 0 endOffset 1 width 4.00: "8"
+          LayoutSVGRect {rect} at (426,251) size 5x40 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=418.04] [y=243.00] [width=4.86] [height=40.00]
+          LayoutSVGText {text} at (418,283) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (418.47,290.00) startOffset 0 endOffset 1 width 4.00: "9"
+          LayoutSVGRect {rect} at (58,319) size 16x55 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=50.00] [y=311.00] [width=15.62] [height=55.00]
+          LayoutSVGText {text} at (55,366) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (55.81,373.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (73,319) size 50x55 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=65.62] [y=311.00] [width=49.07] [height=55.00]
+          LayoutSVGText {text} at (88,366) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (88.15,373.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (122,319) size 26x55 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=114.69] [y=311.00] [width=25.28] [height=55.00]
+          LayoutSVGText {text} at (125,366) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (125.32,373.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (147,319) size 27x55 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=139.96] [y=311.00] [width=25.28] [height=55.00]
+          LayoutSVGText {text} at (150,366) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (150.60,373.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (208,327) size 12x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=200.00] [y=319.00] [width=11.66] [height=40.00]
+          LayoutSVGText {text} at (203,359) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (203.83,366.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (219,327) size 50x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=211.66] [y=319.00] [width=49.07] [height=40.00]
+          LayoutSVGText {text} at (234,359) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (234.19,366.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (268,327) size 6x40 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=260.72] [y=319.00] [width=5.06] [height=40.00]
+          LayoutSVGText {text} at (261,359) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (261.25,366.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (273,327) size 6x40 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=265.78] [y=319.00] [width=5.06] [height=40.00]
+          LayoutSVGText {text} at (266,359) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (266.31,366.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (358,326) size 5x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=350.00] [y=318.00] [width=4.86] [height=40.00]
+          LayoutSVGText {text} at (350,358) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (350.43,365.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (362,326) size 50x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=354.86] [y=318.00] [width=49.07] [height=40.00]
+          LayoutSVGText {text} at (377,358) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (377.40,365.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (411,326) size 5x40 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=403.93] [y=318.00] [width=3.89] [height=40.00]
+          LayoutSVGText {text} at (403,358) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (403.87,365.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (415,326) size 5x40 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=407.82] [y=318.00] [width=3.89] [height=40.00]
+          LayoutSVGText {text} at (407,358) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (407.76,365.00) startOffset 0 endOffset 1 width 4.00: "3"
+        LayoutSVGContainer {g} at (50,18) size 382x357
+          LayoutSVGText {text} at (50,10) size 50x56 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 50x56
+              chunk 1 text run 1 at (50.00,50.00) startOffset 0 endOffset 6 width 48.33: "ab\x{30C}c\x{30C}\x{30C}"
+          LayoutSVGText {text} at (200,15) size 49x44 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 49x44
+              chunk 1 text run 1 at (200.00,50.00) startOffset 0 endOffset 6 width 48.57: "ab\x{30C}c\x{30C}\x{30C}"
+          LayoutSVGText {text} at (350,16) size 57x42 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 57x42
+              chunk 1 text run 1 at (350.00,50.00) startOffset 0 endOffset 6 width 56.43: "ab\x{30C}c\x{30C}\x{30C}"
+          LayoutSVGText {text} at (51,86) size 50x55 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 49x55
+              chunk 1 text run 1 at (51.67,125.00) startOffset 0 endOffset 3 width 13.40: "c\x{30C}\x{30C}"
+              chunk 1 text run 1 at (65.07,125.00) startOffset 0 endOffset 1 width 0.00 RTL: "\x{200F}"
+              chunk 1 text run 1 at (65.07,125.00) startOffset 0 endOffset 2 width 16.97: "b\x{30C}"
+              chunk 1 text run 1 at (82.04,125.00) startOffset 0 endOffset 1 width 0.00 RTL: "\x{200F}"
+              chunk 1 text run 1 at (82.04,125.00) startOffset 0 endOffset 1 width 17.96: "a"
+              chunk 1 text run 1 at (100.00,125.00) startOffset 0 endOffset 1 width 0.00 RTL: "\x{200F}"
+          LayoutSVGText {text} at (200,94) size 50x40 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 50x40
+              chunk 1 text run 1 at (201.43,125.00) startOffset 0 endOffset 3 width 15.53: "c\x{30C}\x{30C}"
+              chunk 1 text run 1 at (216.97,125.00) startOffset 0 endOffset 1 width 0.00 RTL: "\x{200F}"
+              chunk 1 text run 1 at (216.97,125.00) startOffset 0 endOffset 2 width 17.50: "b\x{30C}"
+              chunk 1 text run 1 at (234.47,125.00) startOffset 0 endOffset 1 width 0.00 RTL: "\x{200F}"
+              chunk 1 text run 1 at (234.47,125.00) startOffset 0 endOffset 1 width 15.53: "a"
+              chunk 1 text run 1 at (250.00,125.00) startOffset 0 endOffset 1 width 0.00 RTL: "\x{200F}"
+          LayoutSVGText {text} at (328,93) size 72x40 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 72x40
+              chunk 1 text run 1 at (343.57,125.00) startOffset 0 endOffset 3 width 17.50: "c\x{30C}\x{30C}"
+              chunk 1 text run 1 at (361.07,125.00) startOffset 0 endOffset 1 width 0.00 RTL: "\x{200F}"
+              chunk 1 text run 1 at (361.07,125.00) startOffset 0 endOffset 2 width 19.47: "b\x{30C}"
+              chunk 1 text run 1 at (380.53,125.00) startOffset 0 endOffset 1 width 0.00 RTL: "\x{200F}"
+              chunk 1 text run 1 at (380.53,125.00) startOffset 0 endOffset 1 width 19.47: "a"
+              chunk 1 text run 1 at (400.00,125.00) startOffset 0 endOffset 1 width 0.00 RTL: "\x{200F}"
+          LayoutSVGText {text} at (42,160) size 81x56 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 81x56
+              chunk 1 text run 1 at (50.00,200.00) startOffset 0 endOffset 9 width 71.13: "fi\x{30C} ffi\x{30C}\x{30C}"
+          LayoutSVGText {text} at (200,169) size 64x40 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 64x40
+              chunk 1 text run 1 at (200.00,200.00) startOffset 0 endOffset 9 width 63.20: "fi\x{30C} ffi\x{30C}\x{30C}"
+          LayoutSVGText {text} at (350,166) size 55x42 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 55x42
+              chunk 1 text run 1 at (350.00,200.00) startOffset 0 endOffset 9 width 54.69: "fi\x{30C} ffi\x{30C}\x{30C}"
+          LayoutSVGText {text} at (42,236) size 99x55 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 99x55
+              chunk 1 text run 1 at (50.00,275.00) startOffset 0 endOffset 3 width 24.11: "ff\x{30C}"
+              chunk 1 text run 1 at (74.11,275.00) startOffset 0 endOffset 4 width 34.65 RTL: "\x{640}\x{640}\x{644}\x{627}"
+              chunk 1 text run 1 at (108.77,275.00) startOffset 0 endOffset 3 width 24.11: "ff\x{30C}"
+          LayoutSVGText {text} at (200,244) size 82x40 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 82x40
+              chunk 1 text run 1 at (200.00,275.00) startOffset 0 endOffset 3 width 22.70: "ff\x{30C}"
+              chunk 1 text run 1 at (222.70,275.00) startOffset 0 endOffset 4 width 34.65 RTL: "\x{640}\x{640}\x{644}\x{627}"
+              chunk 1 text run 1 at (257.35,275.00) startOffset 0 endOffset 3 width 22.70: "ff\x{30C}"
+          LayoutSVGText {text} at (350,243) size 74x40 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 74x40
+              chunk 1 text run 1 at (350.00,275.00) startOffset 0 endOffset 3 width 19.12: "ff\x{30C}"
+              chunk 1 text run 1 at (369.12,275.00) startOffset 0 endOffset 4 width 34.65 RTL: "\x{640}\x{640}\x{644}\x{627}"
+              chunk 1 text run 1 at (403.78,275.00) startOffset 0 endOffset 3 width 19.12: "ff\x{30C}"
+          LayoutSVGText {text} at (50,311) size 116x56 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 116x56
+              chunk 1 text run 1 at (50.00,350.00) startOffset 0 endOffset 1 width 15.62: "\x{30C}"
+              chunk 1 text run 1 at (65.62,350.00) startOffset 0 endOffset 1 width 49.07 RTL: "\x{FDB0}"
+              chunk 1 text run 1 at (114.69,350.00) startOffset 0 endOffset 2 width 50.55: "i\x{333}"
+          LayoutSVGText {text} at (199,319) size 84x48 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 83x48
+              chunk 1 text run 1 at (200.00,350.00) startOffset 0 endOffset 1 width 11.66: "\x{30C}"
+              chunk 1 text run 1 at (211.66,350.00) startOffset 0 endOffset 1 width 49.07 RTL: "\x{FDB0}"
+              chunk 1 text run 1 at (260.72,350.00) startOffset 0 endOffset 2 width 10.12: "i\x{333}"
+          LayoutSVGText {text} at (335,318) size 81x49 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 81x49
+              chunk 1 text run 1 at (350.00,350.00) startOffset 0 endOffset 1 width 4.86: "\x{30C}"
+              chunk 1 text run 1 at (354.86,350.00) startOffset 0 endOffset 1 width 49.07 RTL: "\x{FDB0}"
+              chunk 1 text run 1 at (403.93,350.00) startOffset 0 endOffset 2 width 7.78: "i\x{333}"
+      LayoutText {#text} at (0,0) size 0x0
+      LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/text/combining-character-queries-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/text/combining-character-queries-expected.png
new file mode 100644
index 0000000..df0a4752
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/svg/text/combining-character-queries-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/text/combining-character-queries-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/svg/text/combining-character-queries-expected.txt
new file mode 100644
index 0000000..5a1ee7a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/svg/text/combining-character-queries-expected.txt
@@ -0,0 +1,538 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x520
+  LayoutBlockFlow {HTML} at (0,0) size 800x520
+    LayoutBlockFlow {BODY} at (8,8) size 784x504
+      LayoutSVGRoot {svg} at (50,18) size 391x365
+        LayoutSVGContainer {g} at (56,19) size 385x364
+          LayoutSVGRect {rect} at (58,19) size 18x55 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=50.00] [y=11.00] [width=17.96] [height=55.00]
+          LayoutSVGText {text} at (56,66) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (56.98,73.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (75,19) size 10x55 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=67.96] [y=11.00] [width=8.49] [height=55.00]
+          LayoutSVGText {text} at (70,66) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (70.20,73.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (84,19) size 9x55 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=76.45] [y=11.00] [width=8.49] [height=55.00]
+          LayoutSVGText {text} at (78,66) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (78.69,73.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (92,19) size 6x55 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=84.93] [y=11.00] [width=4.47] [height=55.00]
+          LayoutSVGText {text} at (85,66) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (85.16,73.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (97,19) size 5x55 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=89.40] [y=11.00] [width=4.47] [height=55.00]
+          LayoutSVGText {text} at (89,66) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (89.63,73.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (101,19) size 6x55 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=93.86] [y=11.00] [width=4.47] [height=55.00]
+          LayoutSVGText {text} at (94,66) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (94.10,73.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (208,27) size 16x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=200.00] [y=19.00] [width=15.53] [height=40.00]
+          LayoutSVGText {text} at (205,59) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (205.77,66.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (223,27) size 10x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=215.53] [y=19.00] [width=8.75] [height=40.00]
+          LayoutSVGText {text} at (217,59) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (217.91,66.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (232,27) size 10x40 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=224.28] [y=19.00] [width=8.75] [height=40.00]
+          LayoutSVGText {text} at (226,59) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (226.66,66.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (241,27) size 6x40 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=233.03] [y=19.00] [width=5.18] [height=40.00]
+          LayoutSVGText {text} at (233,59) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (233.62,66.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (246,27) size 6x40 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=238.21] [y=19.00] [width=5.18] [height=40.00]
+          LayoutSVGText {text} at (238,59) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (238.80,66.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (251,27) size 6x40 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=243.39] [y=19.00] [width=5.18] [height=40.00]
+          LayoutSVGText {text} at (243,59) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (243.98,66.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (358,26) size 20x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=350.00] [y=18.00] [width=19.47] [height=40.00]
+          LayoutSVGText {text} at (357,58) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (357.73,65.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (377,26) size 11x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=369.47] [y=18.00] [width=9.73] [height=40.00]
+          LayoutSVGText {text} at (372,58) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (372.33,65.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (387,26) size 10x40 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=379.20] [y=18.00] [width=9.73] [height=40.00]
+          LayoutSVGText {text} at (382,58) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (382.06,65.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (396,26) size 8x40 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=388.93] [y=18.00] [width=6.19] [height=40.00]
+          LayoutSVGText {text} at (390,58) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (390.03,65.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (403,26) size 7x40 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=395.12] [y=18.00] [width=6.19] [height=40.00]
+          LayoutSVGText {text} at (396,58) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (396.22,65.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (409,26) size 7x40 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=401.32] [y=18.00] [width=6.19] [height=40.00]
+          LayoutSVGText {text} at (402,58) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (402.41,65.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (8,8) size 0x0 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=100.00] [y=86.00] [width=0.00] [height=55.00]
+          LayoutSVGText {text} at (97,141) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (98.00,148.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (90,94) size 18x55 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=82.04] [y=86.00] [width=17.96] [height=55.00]
+          LayoutSVGText {text} at (89,141) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (89.02,148.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (8,8) size 0x0 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=82.04] [y=86.00] [width=0.00] [height=55.00]
+          LayoutSVGText {text} at (80,141) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (80.04,148.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (73,94) size 9x55 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=65.07] [y=86.00] [width=8.49] [height=55.00]
+          LayoutSVGText {text} at (67,141) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (67.31,148.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (81,94) size 10x55 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=73.55] [y=86.00] [width=8.49] [height=55.00]
+          LayoutSVGText {text} at (75,141) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (75.80,148.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (8,8) size 0x0 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=65.07] [y=86.00] [width=0.00] [height=55.00]
+          LayoutSVGText {text} at (63,141) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (63.07,148.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (59,94) size 6x55 [fill={[type=SOLID] [color=#EE82EE] [opacity=0.30]}] [x=51.67] [y=86.00] [width=4.47] [height=55.00]
+          LayoutSVGText {text} at (51,141) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (51.90,148.00) startOffset 0 endOffset 1 width 4.00: "6"
+          LayoutSVGRect {rect} at (64,94) size 5x55 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=56.14] [y=86.00] [width=4.47] [height=55.00]
+          LayoutSVGText {text} at (56,141) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (56.37,148.00) startOffset 0 endOffset 1 width 4.00: "7"
+          LayoutSVGRect {rect} at (68,94) size 6x55 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=60.60] [y=86.00] [width=4.47] [height=55.00]
+          LayoutSVGText {text} at (60,141) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (60.84,148.00) startOffset 0 endOffset 1 width 4.00: "8"
+          LayoutSVGRect {rect} at (8,8) size 0x0 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=250.00] [y=94.00] [width=0.00] [height=40.00]
+          LayoutSVGText {text} at (248,134) size 4x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (248.00,141.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (242,102) size 16x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=234.47] [y=94.00] [width=15.53] [height=40.00]
+          LayoutSVGText {text} at (240,134) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (240.23,141.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (8,8) size 0x0 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=234.47] [y=94.00] [width=0.00] [height=40.00]
+          LayoutSVGText {text} at (232,134) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (232.47,141.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (224,102) size 10x40 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=216.97] [y=94.00] [width=8.75] [height=40.00]
+          LayoutSVGText {text} at (219,134) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (219.34,141.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (233,102) size 10x40 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=225.72] [y=94.00] [width=8.75] [height=40.00]
+          LayoutSVGText {text} at (228,134) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (228.09,141.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (8,8) size 0x0 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=216.97] [y=94.00] [width=0.00] [height=40.00]
+          LayoutSVGText {text} at (214,134) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (214.97,141.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (209,102) size 6x40 [fill={[type=SOLID] [color=#EE82EE] [opacity=0.30]}] [x=201.43] [y=94.00] [width=5.18] [height=40.00]
+          LayoutSVGText {text} at (202,134) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (202.02,141.00) startOffset 0 endOffset 1 width 4.00: "6"
+          LayoutSVGRect {rect} at (214,102) size 6x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=206.61] [y=94.00] [width=5.18] [height=40.00]
+          LayoutSVGText {text} at (207,134) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (207.20,141.00) startOffset 0 endOffset 1 width 4.00: "7"
+          LayoutSVGRect {rect} at (219,102) size 6x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=211.79] [y=94.00] [width=5.18] [height=40.00]
+          LayoutSVGText {text} at (212,134) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (212.38,141.00) startOffset 0 endOffset 1 width 4.00: "8"
+          LayoutSVGRect {rect} at (8,8) size 0x0 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=400.00] [y=93.00] [width=0.00] [height=40.00]
+          LayoutSVGText {text} at (398,133) size 4x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (398.00,140.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (388,101) size 20x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=380.53] [y=93.00] [width=19.47] [height=40.00]
+          LayoutSVGText {text} at (388,133) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (388.27,140.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (8,8) size 0x0 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=380.53] [y=93.00] [width=0.00] [height=40.00]
+          LayoutSVGText {text} at (378,133) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (378.53,140.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (368,101) size 11x40 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=360.73] [y=93.00] [width=9.90] [height=40.00]
+          LayoutSVGText {text} at (363,133) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (363.68,140.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (378,101) size 11x40 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=370.63] [y=93.00] [width=9.90] [height=40.00]
+          LayoutSVGText {text} at (373,133) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (373.58,140.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (8,8) size 0x0 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=360.73] [y=93.00] [width=0.00] [height=40.00]
+          LayoutSVGText {text} at (358,133) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (358.73,140.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (350,101) size 7x40 [fill={[type=SOLID] [color=#EE82EE] [opacity=0.30]}] [x=342.15] [y=93.00] [width=6.19] [height=40.00]
+          LayoutSVGText {text} at (343,133) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (343.25,140.00) startOffset 0 endOffset 1 width 4.00: "6"
+          LayoutSVGRect {rect} at (356,101) size 7x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=348.34] [y=93.00] [width=6.19] [height=40.00]
+          LayoutSVGText {text} at (349,133) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (349.44,140.00) startOffset 0 endOffset 1 width 4.00: "7"
+          LayoutSVGRect {rect} at (362,101) size 7x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=354.54] [y=93.00] [width=6.19] [height=40.00]
+          LayoutSVGText {text} at (355,133) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (355.63,140.00) startOffset 0 endOffset 1 width 4.00: "8"
+          LayoutSVGRect {rect} at (58,169) size 6x55 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=50.00] [y=161.00] [width=5.97] [height=55.00]
+          LayoutSVGText {text} at (50,216) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (50.99,223.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (63,169) size 18x55 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=55.97] [y=161.00] [width=16.27] [height=55.00]
+          LayoutSVGText {text} at (62,216) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (62.11,223.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (80,169) size 17x55 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=72.24] [y=161.00] [width=16.27] [height=55.00]
+          LayoutSVGText {text} at (78,216) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (78.37,223.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (96,169) size 11x55 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=88.50] [y=161.00] [width=9.72] [height=55.00]
+          LayoutSVGText {text} at (91,216) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (91.37,223.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (106,169) size 1x55 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=98.23] [y=161.00] [width=0.42] [height=55.00]
+          LayoutSVGText {text} at (96,216) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (96.44,223.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (106,169) size 2x55 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=98.65] [y=161.00] [width=0.42] [height=55.00]
+          LayoutSVGText {text} at (96,216) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (96.86,223.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (107,169) size 13x55 [fill={[type=SOLID] [color=#EE82EE] [opacity=0.30]}] [x=99.06] [y=161.00] [width=12.56] [height=55.00]
+          LayoutSVGText {text} at (103,216) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (103.35,223.00) startOffset 0 endOffset 1 width 4.00: "6"
+          LayoutSVGRect {rect} at (119,169) size 14x55 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=111.63] [y=161.00] [width=12.56] [height=55.00]
+          LayoutSVGText {text} at (115,216) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (115.91,223.00) startOffset 0 endOffset 1 width 4.00: "7"
+          LayoutSVGRect {rect} at (132,169) size 13x55 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=124.19] [y=161.00] [width=12.56] [height=55.00]
+          LayoutSVGText {text} at (128,216) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (128.47,223.00) startOffset 0 endOffset 1 width 4.00: "8"
+          LayoutSVGRect {rect} at (208,177) size 12x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=200.00] [y=169.00] [width=11.66] [height=40.00]
+          LayoutSVGText {text} at (203,209) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (203.83,216.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (219,177) size 6x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=211.66] [y=169.00] [width=4.86] [height=40.00]
+          LayoutSVGText {text} at (212,209) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (212.09,216.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (224,177) size 6x40 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=216.52] [y=169.00] [width=4.86] [height=40.00]
+          LayoutSVGText {text} at (216,209) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (216.95,216.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (229,177) size 10x40 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=221.38] [y=169.00] [width=8.75] [height=40.00]
+          LayoutSVGText {text} at (223,209) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (223.75,216.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (238,177) size 12x40 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=230.13] [y=169.00] [width=11.04] [height=40.00]
+          LayoutSVGText {text} at (233,209) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (233.65,216.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (249,177) size 13x40 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=241.17] [y=169.00] [width=12.30] [height=40.00]
+          LayoutSVGText {text} at (245,209) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (245.32,216.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (261,177) size 4x40 [fill={[type=SOLID] [color=#EE82EE] [opacity=0.30]}] [x=253.47] [y=169.00] [width=3.24] [height=40.00]
+          LayoutSVGText {text} at (253,209) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (253.09,216.00) startOffset 0 endOffset 1 width 4.00: "6"
+          LayoutSVGRect {rect} at (264,177) size 4x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=256.72] [y=169.00] [width=3.24] [height=40.00]
+          LayoutSVGText {text} at (256,209) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (256.34,216.00) startOffset 0 endOffset 1 width 4.00: "7"
+          LayoutSVGRect {rect} at (267,177) size 5x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=259.96] [y=169.00] [width=3.24] [height=40.00]
+          LayoutSVGText {text} at (259,209) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (259.58,216.00) startOffset 0 endOffset 1 width 4.00: "8"
+          LayoutSVGRect {rect} at (358,176) size 10x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=350.00] [y=168.00] [width=9.72] [height=40.00]
+          LayoutSVGText {text} at (352,208) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (352.86,215.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (367,176) size 6x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=359.72] [y=168.00] [width=4.86] [height=40.00]
+          LayoutSVGText {text} at (360,208) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (360.16,215.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (372,176) size 6x40 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=364.59] [y=168.00] [width=4.86] [height=40.00]
+          LayoutSVGText {text} at (365,208) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (365.02,215.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (377,176) size 11x40 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=369.45] [y=168.00] [width=9.72] [height=40.00]
+          LayoutSVGText {text} at (372,208) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (372.31,215.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (387,176) size 10x40 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=379.17] [y=168.00] [width=9.11] [height=40.00]
+          LayoutSVGText {text} at (381,208) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (381.73,215.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (396,176) size 11x40 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=388.28] [y=168.00] [width=9.74] [height=40.00]
+          LayoutSVGText {text} at (391,208) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (391.15,215.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (406,176) size 5x40 [fill={[type=SOLID] [color=#EE82EE] [opacity=0.30]}] [x=398.02] [y=168.00] [width=4.94] [height=40.00]
+          LayoutSVGText {text} at (398,208) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (398.49,215.00) startOffset 0 endOffset 1 width 4.00: "6"
+          LayoutSVGRect {rect} at (410,176) size 6x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=402.96] [y=168.00] [width=4.94] [height=40.00]
+          LayoutSVGText {text} at (403,208) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (403.43,215.00) startOffset 0 endOffset 1 width 4.00: "7"
+          LayoutSVGRect {rect} at (415,176) size 6x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=407.90] [y=168.00] [width=4.94] [height=40.00]
+          LayoutSVGText {text} at (408,208) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (408.37,215.00) startOffset 0 endOffset 1 width 4.00: "8"
+          LayoutSVGRect {rect} at (58,244) size 2x55 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=50.00] [y=236.00] [width=1.45] [height=55.00]
+          LayoutSVGText {text} at (48,291) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (48.73,298.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (59,244) size 16x55 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=51.45] [y=236.00] [width=15.24] [height=55.00]
+          LayoutSVGText {text} at (57,291) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (57.07,298.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (74,244) size 16x55 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=66.69] [y=236.00] [width=15.24] [height=55.00]
+          LayoutSVGText {text} at (72,291) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (72.31,298.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (117,244) size 8x55 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=109.47] [y=236.00] [width=7.10] [height=55.00]
+          LayoutSVGText {text} at (111,291) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (111.02,298.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (110,244) size 8x55 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=102.37] [y=236.00] [width=7.10] [height=55.00]
+          LayoutSVGText {text} at (103,291) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (103.92,298.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (100,244) size 11x55 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=92.15] [y=236.00] [width=10.22] [height=55.00]
+          LayoutSVGText {text} at (95,291) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (95.26,298.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (89,244) size 12x55 [fill={[type=SOLID] [color=#EE82EE] [opacity=0.30]}] [x=81.92] [y=236.00] [width=10.22] [height=55.00]
+          LayoutSVGText {text} at (85,291) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (85.03,298.00) startOffset 0 endOffset 1 width 4.00: "6"
+          LayoutSVGRect {rect} at (124,244) size 3x55 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=116.58] [y=236.00] [width=1.45] [height=55.00]
+          LayoutSVGText {text} at (115,291) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (115.30,298.00) startOffset 0 endOffset 1 width 4.00: "7"
+          LayoutSVGRect {rect} at (126,244) size 16x55 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=118.03] [y=236.00] [width=15.24] [height=55.00]
+          LayoutSVGText {text} at (123,291) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (123.65,298.00) startOffset 0 endOffset 1 width 4.00: "8"
+          LayoutSVGRect {rect} at (141,244) size 16x55 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=133.26] [y=236.00] [width=15.24] [height=55.00]
+          LayoutSVGText {text} at (138,291) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (138.88,298.00) startOffset 0 endOffset 1 width 4.00: "9"
+          LayoutSVGRect {rect} at (208,252) size 12x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=200.00] [y=244.00] [width=11.04] [height=40.00]
+          LayoutSVGText {text} at (203,284) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (203.52,291.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (219,252) size 6x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=211.04] [y=244.00] [width=5.83] [height=40.00]
+          LayoutSVGText {text} at (211,284) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (211.95,291.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (224,252) size 7x40 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=216.87] [y=244.00] [width=5.83] [height=40.00]
+          LayoutSVGText {text} at (217,284) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (217.78,291.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (258,252) size 8x40 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=250.24] [y=244.00] [width=7.10] [height=40.00]
+          LayoutSVGText {text} at (251,284) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (251.79,291.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (251,252) size 8x40 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=243.14] [y=244.00] [width=7.10] [height=40.00]
+          LayoutSVGText {text} at (244,284) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (244.69,291.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (240,252) size 12x40 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=232.92] [y=244.00] [width=10.22] [height=40.00]
+          LayoutSVGText {text} at (236,284) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (236.03,291.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (230,252) size 11x40 [fill={[type=SOLID] [color=#EE82EE] [opacity=0.30]}] [x=222.70] [y=244.00] [width=10.22] [height=40.00]
+          LayoutSVGText {text} at (225,284) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (225.81,291.00) startOffset 0 endOffset 1 width 4.00: "6"
+          LayoutSVGRect {rect} at (265,252) size 12x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=257.35] [y=244.00] [width=11.04] [height=40.00]
+          LayoutSVGText {text} at (260,284) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (260.87,291.00) startOffset 0 endOffset 1 width 4.00: "7"
+          LayoutSVGRect {rect} at (276,252) size 7x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=268.39] [y=244.00] [width=5.83] [height=40.00]
+          LayoutSVGText {text} at (269,284) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (269.30,291.00) startOffset 0 endOffset 1 width 4.00: "8"
+          LayoutSVGRect {rect} at (282,252) size 7x40 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=274.21] [y=244.00] [width=5.83] [height=40.00]
+          LayoutSVGText {text} at (275,284) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (275.13,291.00) startOffset 0 endOffset 1 width 4.00: "9"
+          LayoutSVGRect {rect} at (358,251) size 10x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=350.00] [y=243.00] [width=9.40] [height=40.00]
+          LayoutSVGText {text} at (352,283) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (352.70,290.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (367,251) size 8x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=359.40] [y=243.00] [width=7.27] [height=40.00]
+          LayoutSVGText {text} at (361,283) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (361.04,290.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (374,251) size 8x40 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=366.67] [y=243.00] [width=7.27] [height=40.00]
+          LayoutSVGText {text} at (368,283) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (368.31,290.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (409,251) size 8x40 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=401.49] [y=243.00] [width=7.10] [height=40.00]
+          LayoutSVGText {text} at (403,283) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (403.04,290.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (402,251) size 8x40 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=394.39] [y=243.00] [width=7.10] [height=40.00]
+          LayoutSVGText {text} at (395,283) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (395.94,290.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (392,251) size 11x40 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=384.16] [y=243.00] [width=10.22] [height=40.00]
+          LayoutSVGText {text} at (387,283) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (387.28,290.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (381,251) size 12x40 [fill={[type=SOLID] [color=#EE82EE] [opacity=0.30]}] [x=373.94] [y=243.00] [width=10.22] [height=40.00]
+          LayoutSVGText {text} at (377,283) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (377.05,290.00) startOffset 0 endOffset 1 width 4.00: "6"
+          LayoutSVGRect {rect} at (416,251) size 10x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=408.59] [y=243.00] [width=9.40] [height=40.00]
+          LayoutSVGText {text} at (411,283) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (411.29,290.00) startOffset 0 endOffset 1 width 4.00: "7"
+          LayoutSVGRect {rect} at (425,251) size 9x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=417.99] [y=243.00] [width=7.27] [height=40.00]
+          LayoutSVGText {text} at (419,283) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (419.63,290.00) startOffset 0 endOffset 1 width 4.00: "8"
+          LayoutSVGRect {rect} at (433,251) size 8x40 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=425.27] [y=243.00] [width=7.27] [height=40.00]
+          LayoutSVGText {text} at (426,283) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (426.90,290.00) startOffset 0 endOffset 1 width 4.00: "9"
+          LayoutSVGRect {rect} at (58,319) size 16x55 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=50.00] [y=311.00] [width=15.62] [height=55.00]
+          LayoutSVGText {text} at (55,366) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (55.81,373.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (73,319) size 50x55 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=65.62] [y=311.00] [width=49.07] [height=55.00]
+          LayoutSVGText {text} at (88,366) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (88.15,373.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (122,319) size 26x55 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=114.69] [y=311.00] [width=25.28] [height=55.00]
+          LayoutSVGText {text} at (125,366) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (125.32,373.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (147,319) size 27x55 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=139.96] [y=311.00] [width=25.28] [height=55.00]
+          LayoutSVGText {text} at (150,366) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (150.60,373.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (208,327) size 13x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=200.00] [y=319.00] [width=12.24] [height=40.00]
+          LayoutSVGText {text} at (204,359) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (204.12,366.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (220,327) size 50x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=212.24] [y=319.00] [width=49.07] [height=40.00]
+          LayoutSVGText {text} at (234,359) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (234.77,366.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (269,327) size 12x40 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=261.30] [y=319.00] [width=10.75] [height=40.00]
+          LayoutSVGText {text} at (264,359) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (264.68,366.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (280,327) size 11x40 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=272.05] [y=319.00] [width=10.75] [height=40.00]
+          LayoutSVGText {text} at (275,359) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (275.43,366.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (358,326) size 15x40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=350.00] [y=318.00] [width=14.83] [height=40.00]
+          LayoutSVGText {text} at (355,358) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (355.42,365.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (372,326) size 50x40 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=364.83] [y=318.00] [width=49.07] [height=40.00]
+          LayoutSVGText {text} at (387,358) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (387.37,365.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (421,326) size 9x40 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=413.90] [y=318.00] [width=7.88] [height=40.00]
+          LayoutSVGText {text} at (415,358) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (415.84,365.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (429,326) size 9x40 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=421.78] [y=318.00] [width=7.88] [height=40.00]
+          LayoutSVGText {text} at (423,358) size 5x9 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x9
+              chunk 1 (middle anchor) text run 1 at (423.72,365.00) startOffset 0 endOffset 1 width 4.00: "3"
+        LayoutSVGContainer {g} at (50,18) size 391x357
+          LayoutSVGText {text} at (50,10) size 50x56 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 50x56
+              chunk 1 text run 1 at (50.00,50.00) startOffset 0 endOffset 6 width 48.33: "ab\x{30C}c\x{30C}\x{30C}"
+          LayoutSVGText {text} at (200,15) size 49x44 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 49x44
+              chunk 1 text run 1 at (200.00,50.00) startOffset 0 endOffset 6 width 48.57: "ab\x{30C}c\x{30C}\x{30C}"
+          LayoutSVGText {text} at (350,16) size 58x42 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 58x42
+              chunk 1 text run 1 at (350.00,50.00) startOffset 0 endOffset 6 width 57.51: "ab\x{30C}c\x{30C}\x{30C}"
+          LayoutSVGText {text} at (51,79) size 50x62 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,6) size 49x62
+              chunk 1 text run 1 at (51.67,125.00) startOffset 0 endOffset 3 width 13.40: "c\x{30C}\x{30C}"
+              chunk 1 text run 1 at (65.07,125.00) startOffset 0 endOffset 1 width 0.00 RTL: "\x{200F}"
+              chunk 1 text run 1 at (65.07,125.00) startOffset 0 endOffset 2 width 16.97: "b\x{30C}"
+              chunk 1 text run 1 at (82.04,125.00) startOffset 0 endOffset 1 width 0.00 RTL: "\x{200F}"
+              chunk 1 text run 1 at (82.04,125.00) startOffset 0 endOffset 1 width 17.96: "a"
+              chunk 1 text run 1 at (100.00,125.00) startOffset 0 endOffset 1 width 0.00 RTL: "\x{200F}"
+          LayoutSVGText {text} at (200,90) size 50x44 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 50x44
+              chunk 1 text run 1 at (201.43,125.00) startOffset 0 endOffset 3 width 15.53: "c\x{30C}\x{30C}"
+              chunk 1 text run 1 at (216.97,125.00) startOffset 0 endOffset 1 width 0.00 RTL: "\x{200F}"
+              chunk 1 text run 1 at (216.97,125.00) startOffset 0 endOffset 2 width 17.50: "b\x{30C}"
+              chunk 1 text run 1 at (234.47,125.00) startOffset 0 endOffset 1 width 0.00 RTL: "\x{200F}"
+              chunk 1 text run 1 at (234.47,125.00) startOffset 0 endOffset 1 width 15.53: "a"
+              chunk 1 text run 1 at (250.00,125.00) startOffset 0 endOffset 1 width 0.00 RTL: "\x{200F}"
+          LayoutSVGText {text} at (327,91) size 73x42 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 73x42
+              chunk 1 text run 1 at (342.15,125.00) startOffset 0 endOffset 3 width 18.58: "c\x{30C}\x{30C}"
+              chunk 1 text run 1 at (360.73,125.00) startOffset 0 endOffset 1 width 0.00 RTL: "\x{200F}"
+              chunk 1 text run 1 at (360.73,125.00) startOffset 0 endOffset 2 width 19.81: "b\x{30C}"
+              chunk 1 text run 1 at (380.53,125.00) startOffset 0 endOffset 1 width 0.00 RTL: "\x{200F}"
+              chunk 1 text run 1 at (380.53,125.00) startOffset 0 endOffset 1 width 19.47: "a"
+              chunk 1 text run 1 at (400.00,125.00) startOffset 0 endOffset 1 width 0.00 RTL: "\x{200F}"
+          LayoutSVGText {text} at (42,160) size 95x56 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 95x56
+              chunk 1 text run 1 at (50.00,200.00) startOffset 0 endOffset 9 width 86.75: "fi\x{30C} ffi\x{30C}\x{30C}"
+          LayoutSVGText {text} at (200,169) size 64x40 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 64x40
+              chunk 1 text run 1 at (200.00,200.00) startOffset 0 endOffset 9 width 63.20: "fi\x{30C} ffi\x{30C}\x{30C}"
+          LayoutSVGText {text} at (350,168) size 63x40 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 63x40
+              chunk 1 text run 1 at (350.00,200.00) startOffset 0 endOffset 9 width 62.84: "fi\x{30C} ffi\x{30C}\x{30C}"
+          LayoutSVGText {text} at (42,236) size 107x55 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 107x55
+              chunk 1 text run 1 at (50.00,275.00) startOffset 0 endOffset 3 width 31.92: "ff\x{30C}"
+              chunk 1 text run 1 at (81.92,275.00) startOffset 0 endOffset 4 width 34.65 RTL: "\x{640}\x{640}\x{644}\x{627}"
+              chunk 1 text run 1 at (116.58,275.00) startOffset 0 endOffset 3 width 31.92: "ff\x{30C}"
+          LayoutSVGText {text} at (200,244) size 82x40 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 82x40
+              chunk 1 text run 1 at (200.00,275.00) startOffset 0 endOffset 3 width 22.70: "ff\x{30C}"
+              chunk 1 text run 1 at (222.70,275.00) startOffset 0 endOffset 4 width 34.65 RTL: "\x{640}\x{640}\x{644}\x{627}"
+              chunk 1 text run 1 at (257.35,275.00) startOffset 0 endOffset 3 width 22.70: "ff\x{30C}"
+          LayoutSVGText {text} at (350,243) size 83x40 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 83x40
+              chunk 1 text run 1 at (350.00,275.00) startOffset 0 endOffset 3 width 23.94: "ff\x{30C}"
+              chunk 1 text run 1 at (373.94,275.00) startOffset 0 endOffset 4 width 34.65 RTL: "\x{640}\x{640}\x{644}\x{627}"
+              chunk 1 text run 1 at (408.59,275.00) startOffset 0 endOffset 3 width 23.94: "ff\x{30C}"
+          LayoutSVGText {text} at (50,311) size 116x56 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 116x56
+              chunk 1 text run 1 at (50.00,350.00) startOffset 0 endOffset 1 width 15.62: "\x{30C}"
+              chunk 1 text run 1 at (65.62,350.00) startOffset 0 endOffset 1 width 49.07 RTL: "\x{FDB0}"
+              chunk 1 text run 1 at (114.69,350.00) startOffset 0 endOffset 2 width 50.55: "i\x{333}"
+          LayoutSVGText {text} at (199,319) size 84x48 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 84x48
+              chunk 1 text run 1 at (200.00,350.00) startOffset 0 endOffset 1 width 12.24: "\x{30C}"
+              chunk 1 text run 1 at (212.24,350.00) startOffset 0 endOffset 1 width 49.07 RTL: "\x{FDB0}"
+              chunk 1 text run 1 at (261.30,350.00) startOffset 0 endOffset 2 width 21.50: "i\x{333}"
+          LayoutSVGText {text} at (335,318) size 95x49 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 95x49
+              chunk 1 text run 1 at (350.00,350.00) startOffset 0 endOffset 1 width 14.83: "\x{30C}"
+              chunk 1 text run 1 at (364.83,350.00) startOffset 0 endOffset 1 width 49.07 RTL: "\x{FDB0}"
+              chunk 1 text run 1 at (413.90,350.00) startOffset 0 endOffset 2 width 15.76: "i\x{333}"
+      LayoutText {#text} at (0,0) size 0x0
+      LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/text/combining-character-queries-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/text/combining-character-queries-expected.png
new file mode 100644
index 0000000..8cd1faa8
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/svg/text/combining-character-queries-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/text/combining-character-queries-expected.txt b/third_party/WebKit/LayoutTests/platform/win/svg/text/combining-character-queries-expected.txt
new file mode 100644
index 0000000..918ad243
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/svg/text/combining-character-queries-expected.txt
@@ -0,0 +1,538 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x520
+  LayoutBlockFlow {HTML} at (0,0) size 800x520
+    LayoutBlockFlow {BODY} at (8,8) size 784x504
+      LayoutSVGRoot {svg} at (53,19) size 384x358
+        LayoutSVGContainer {g} at (57,19) size 375x358
+          LayoutSVGRect {rect} at (58,19) size 16x49 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=50.00] [y=11.00] [width=15.53] [height=49.00]
+          LayoutSVGText {text} at (55,59) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (55.77,67.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (73,19) size 10x49 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=65.53] [y=11.00] [width=8.75] [height=49.00]
+          LayoutSVGText {text} at (67,59) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (67.91,67.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (82,19) size 10x49 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=74.28] [y=11.00] [width=8.75] [height=49.00]
+          LayoutSVGText {text} at (76,59) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (76.66,67.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (91,19) size 6x49 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=83.03] [y=11.00] [width=5.18] [height=49.00]
+          LayoutSVGText {text} at (83,59) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (83.62,67.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (96,19) size 6x49 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=88.21] [y=11.00] [width=5.18] [height=49.00]
+          LayoutSVGText {text} at (88,59) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (88.80,67.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (101,19) size 6x49 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=93.39] [y=11.00] [width=5.18] [height=49.00]
+          LayoutSVGText {text} at (93,59) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (93.98,67.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (208,27) size 16x39 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=200.00] [y=19.00] [width=15.53] [height=39.00]
+          LayoutSVGText {text} at (205,57) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (205.77,65.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (223,27) size 10x39 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=215.53] [y=19.00] [width=8.75] [height=39.00]
+          LayoutSVGText {text} at (217,57) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (217.91,65.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (232,27) size 10x39 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=224.28] [y=19.00] [width=8.75] [height=39.00]
+          LayoutSVGText {text} at (226,57) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (226.66,65.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (241,27) size 6x39 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=233.03] [y=19.00] [width=5.18] [height=39.00]
+          LayoutSVGText {text} at (233,57) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (233.62,65.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (246,27) size 6x39 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=238.21] [y=19.00] [width=5.18] [height=39.00]
+          LayoutSVGText {text} at (238,57) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (238.80,65.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (251,27) size 6x39 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=243.39] [y=19.00] [width=5.18] [height=39.00]
+          LayoutSVGText {text} at (243,57) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (243.98,65.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (358,26) size 20x39 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=350.00] [y=18.00] [width=19.47] [height=39.00]
+          LayoutSVGText {text} at (357,56) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (357.73,64.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (377,26) size 11x39 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=369.47] [y=18.00] [width=9.73] [height=39.00]
+          LayoutSVGText {text} at (372,56) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (372.33,64.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (387,26) size 10x39 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=379.20] [y=18.00] [width=9.73] [height=39.00]
+          LayoutSVGText {text} at (382,56) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (382.06,64.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (396,26) size 7x39 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=388.93] [y=18.00] [width=5.83] [height=39.00]
+          LayoutSVGText {text} at (389,56) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (389.85,64.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (402,26) size 7x39 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=394.76] [y=18.00] [width=5.83] [height=39.00]
+          LayoutSVGText {text} at (395,56) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (395.68,64.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (408,26) size 7x39 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=400.60] [y=18.00] [width=5.83] [height=39.00]
+          LayoutSVGText {text} at (401,56) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (401.51,64.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (8,8) size 0x0 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=100.00] [y=86.00] [width=0.00] [height=49.00]
+          LayoutSVGText {text} at (98,134) size 4x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (98.00,142.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (90,94) size 18x49 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=82.09] [y=86.00] [width=17.91] [height=49.00]
+          LayoutSVGText {text} at (89,134) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (89.04,142.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (8,8) size 0x0 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=82.09] [y=86.00] [width=0.00] [height=49.00]
+          LayoutSVGText {text} at (80,134) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (80.09,142.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (72,94) size 10x49 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=64.59] [y=86.00] [width=8.75] [height=49.00]
+          LayoutSVGText {text} at (66,134) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (66.96,142.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (81,94) size 10x49 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=73.34] [y=86.00] [width=8.75] [height=49.00]
+          LayoutSVGText {text} at (75,134) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (75.71,142.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (8,8) size 0x0 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=64.59] [y=86.00] [width=0.00] [height=49.00]
+          LayoutSVGText {text} at (62,134) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (62.59,142.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (57,94) size 6x49 [fill={[type=SOLID] [color=#EE82EE] [opacity=0.30]}] [x=49.06] [y=86.00] [width=5.18] [height=49.00]
+          LayoutSVGText {text} at (49,134) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (49.64,142.00) startOffset 0 endOffset 1 width 4.00: "6"
+          LayoutSVGRect {rect} at (62,94) size 6x49 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=54.23] [y=86.00] [width=5.18] [height=49.00]
+          LayoutSVGText {text} at (54,134) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (54.82,142.00) startOffset 0 endOffset 1 width 4.00: "7"
+          LayoutSVGRect {rect} at (67,94) size 6x49 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=59.41] [y=86.00] [width=5.18] [height=49.00]
+          LayoutSVGText {text} at (60,134) size 4x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (60.00,142.00) startOffset 0 endOffset 1 width 4.00: "8"
+          LayoutSVGRect {rect} at (8,8) size 0x0 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=250.00] [y=94.00] [width=0.00] [height=39.00]
+          LayoutSVGText {text} at (248,132) size 4x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (248.00,140.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (242,102) size 16x39 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=234.47] [y=94.00] [width=15.53] [height=39.00]
+          LayoutSVGText {text} at (240,132) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (240.23,140.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (8,8) size 0x0 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=234.47] [y=94.00] [width=0.00] [height=39.00]
+          LayoutSVGText {text} at (232,132) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (232.47,140.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (224,102) size 10x39 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=216.97] [y=94.00] [width=8.75] [height=39.00]
+          LayoutSVGText {text} at (219,132) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (219.34,140.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (233,102) size 10x39 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=225.72] [y=94.00] [width=8.75] [height=39.00]
+          LayoutSVGText {text} at (228,132) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (228.09,140.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (8,8) size 0x0 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=216.97] [y=94.00] [width=0.00] [height=39.00]
+          LayoutSVGText {text} at (214,132) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (214.97,140.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (209,102) size 6x39 [fill={[type=SOLID] [color=#EE82EE] [opacity=0.30]}] [x=201.43] [y=94.00] [width=5.18] [height=39.00]
+          LayoutSVGText {text} at (202,132) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (202.02,140.00) startOffset 0 endOffset 1 width 4.00: "6"
+          LayoutSVGRect {rect} at (214,102) size 6x39 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=206.61] [y=94.00] [width=5.18] [height=39.00]
+          LayoutSVGText {text} at (207,132) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (207.20,140.00) startOffset 0 endOffset 1 width 4.00: "7"
+          LayoutSVGRect {rect} at (219,102) size 6x39 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=211.79] [y=94.00] [width=5.18] [height=39.00]
+          LayoutSVGText {text} at (212,132) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (212.38,140.00) startOffset 0 endOffset 1 width 4.00: "8"
+          LayoutSVGRect {rect} at (8,8) size 0x0 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=400.00] [y=93.00] [width=0.00] [height=39.00]
+          LayoutSVGText {text} at (398,131) size 4x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (398.00,139.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (388,101) size 20x39 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=380.53] [y=93.00] [width=19.47] [height=39.00]
+          LayoutSVGText {text} at (388,131) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (388.27,139.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (8,8) size 0x0 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=380.53] [y=93.00] [width=0.00] [height=39.00]
+          LayoutSVGText {text} at (378,131) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (378.53,139.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (369,101) size 10x39 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=361.07] [y=93.00] [width=9.73] [height=39.00]
+          LayoutSVGText {text} at (363,131) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (363.94,139.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (378,101) size 11x39 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=370.80] [y=93.00] [width=9.73] [height=39.00]
+          LayoutSVGText {text} at (373,131) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (373.67,139.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (8,8) size 0x0 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=361.07] [y=93.00] [width=0.00] [height=39.00]
+          LayoutSVGText {text} at (359,131) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (359.07,139.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (351,101) size 7x39 [fill={[type=SOLID] [color=#EE82EE] [opacity=0.30]}] [x=343.57] [y=93.00] [width=5.83] [height=39.00]
+          LayoutSVGText {text} at (344,131) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (344.49,139.00) startOffset 0 endOffset 1 width 4.00: "6"
+          LayoutSVGRect {rect} at (357,101) size 7x39 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=349.40] [y=93.00] [width=5.83] [height=39.00]
+          LayoutSVGText {text} at (350,131) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (350.32,139.00) startOffset 0 endOffset 1 width 4.00: "7"
+          LayoutSVGRect {rect} at (363,101) size 7x39 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=355.24] [y=93.00] [width=5.83] [height=39.00]
+          LayoutSVGText {text} at (356,131) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (356.15,139.00) startOffset 0 endOffset 1 width 4.00: "8"
+          LayoutSVGRect {rect} at (58,169) size 12x49 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=50.00] [y=161.00] [width=11.66] [height=49.00]
+          LayoutSVGText {text} at (53,209) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (53.83,217.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (69,169) size 6x49 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=61.66] [y=161.00] [width=4.86] [height=49.00]
+          LayoutSVGText {text} at (62,209) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (62.09,217.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (74,169) size 6x49 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=66.52] [y=161.00] [width=4.86] [height=49.00]
+          LayoutSVGText {text} at (66,209) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (66.95,217.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (79,169) size 11x49 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=71.38] [y=161.00] [width=10.46] [height=49.00]
+          LayoutSVGText {text} at (74,209) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (74.61,217.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (89,169) size 12x49 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=81.84] [y=161.00] [width=11.02] [height=49.00]
+          LayoutSVGText {text} at (85,209) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (85.35,217.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (100,169) size 13x49 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=92.86] [y=161.00] [width=11.66] [height=49.00]
+          LayoutSVGText {text} at (96,209) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (96.69,217.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (112,169) size 4x49 [fill={[type=SOLID] [color=#EE82EE] [opacity=0.30]}] [x=104.52] [y=161.00] [width=3.24] [height=49.00]
+          LayoutSVGText {text} at (104,209) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (104.14,217.00) startOffset 0 endOffset 1 width 4.00: "6"
+          LayoutSVGRect {rect} at (115,169) size 4x49 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=107.76] [y=161.00] [width=3.24] [height=49.00]
+          LayoutSVGText {text} at (107,209) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (107.38,217.00) startOffset 0 endOffset 1 width 4.00: "7"
+          LayoutSVGRect {rect} at (118,169) size 5x49 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=111.00] [y=161.00] [width=3.24] [height=49.00]
+          LayoutSVGText {text} at (110,209) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (110.62,217.00) startOffset 0 endOffset 1 width 4.00: "8"
+          LayoutSVGRect {rect} at (208,177) size 12x39 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=200.00] [y=169.00] [width=11.66] [height=39.00]
+          LayoutSVGText {text} at (203,207) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (203.83,215.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (219,177) size 6x39 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=211.66] [y=169.00] [width=4.86] [height=39.00]
+          LayoutSVGText {text} at (212,207) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (212.09,215.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (224,177) size 6x39 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=216.52] [y=169.00] [width=4.86] [height=39.00]
+          LayoutSVGText {text} at (216,207) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (216.95,215.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (229,177) size 10x39 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=221.38] [y=169.00] [width=8.75] [height=39.00]
+          LayoutSVGText {text} at (223,207) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (223.75,215.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (238,177) size 12x39 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=230.13] [y=169.00] [width=11.02] [height=39.00]
+          LayoutSVGText {text} at (233,207) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (233.64,215.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (249,177) size 12x39 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=241.15] [y=169.00] [width=11.66] [height=39.00]
+          LayoutSVGText {text} at (244,207) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (244.98,215.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (260,177) size 5x39 [fill={[type=SOLID] [color=#EE82EE] [opacity=0.30]}] [x=252.81] [y=169.00] [width=3.24] [height=39.00]
+          LayoutSVGText {text} at (252,207) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (252.43,215.00) startOffset 0 endOffset 1 width 4.00: "6"
+          LayoutSVGRect {rect} at (264,177) size 4x39 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=256.05] [y=169.00] [width=3.24] [height=39.00]
+          LayoutSVGText {text} at (255,207) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (255.67,215.00) startOffset 0 endOffset 1 width 4.00: "7"
+          LayoutSVGRect {rect} at (267,177) size 4x39 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=259.29] [y=169.00] [width=3.24] [height=39.00]
+          LayoutSVGText {text} at (258,207) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (258.91,215.00) startOffset 0 endOffset 1 width 4.00: "8"
+          LayoutSVGRect {rect} at (358,176) size 10x39 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=350.00] [y=168.00] [width=9.72] [height=39.00]
+          LayoutSVGText {text} at (352,206) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (352.86,214.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (367,176) size 5x39 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=359.72] [y=168.00] [width=3.89] [height=39.00]
+          LayoutSVGText {text} at (359,206) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (359.67,214.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (371,176) size 5x39 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=363.61] [y=168.00] [width=3.89] [height=39.00]
+          LayoutSVGText {text} at (363,206) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (363.56,214.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (375,176) size 11x39 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=367.50] [y=168.00] [width=9.72] [height=39.00]
+          LayoutSVGText {text} at (370,206) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (370.36,214.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (385,176) size 10x39 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=377.22] [y=168.00] [width=9.09] [height=39.00]
+          LayoutSVGText {text} at (379,206) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (379.77,214.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (394,176) size 11x39 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=386.32] [y=168.00] [width=9.72] [height=39.00]
+          LayoutSVGText {text} at (389,206) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (389.18,214.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (404,176) size 3x39 [fill={[type=SOLID] [color=#EE82EE] [opacity=0.30]}] [x=396.04] [y=168.00] [width=2.59] [height=39.00]
+          LayoutSVGText {text} at (395,206) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (395.34,214.00) startOffset 0 endOffset 1 width 4.00: "6"
+          LayoutSVGRect {rect} at (406,176) size 4x39 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=398.63] [y=168.00] [width=2.59] [height=39.00]
+          LayoutSVGText {text} at (397,206) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (397.93,214.00) startOffset 0 endOffset 1 width 4.00: "7"
+          LayoutSVGRect {rect} at (409,176) size 3x39 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=401.22] [y=168.00] [width=2.59] [height=39.00]
+          LayoutSVGText {text} at (400,206) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (400.52,214.00) startOffset 0 endOffset 1 width 4.00: "8"
+          LayoutSVGRect {rect} at (58,244) size 12x49 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=50.00] [y=236.00] [width=11.02] [height=49.00]
+          LayoutSVGText {text} at (53,284) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (53.51,292.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (69,244) size 6x49 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=61.02] [y=236.00] [width=5.83] [height=49.00]
+          LayoutSVGText {text} at (61,284) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (61.94,292.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (74,244) size 7x49 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=66.85] [y=236.00] [width=5.83] [height=49.00]
+          LayoutSVGText {text} at (67,284) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (67.76,292.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (108,244) size 9x49 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=100.94] [y=236.00] [width=7.25] [height=49.00]
+          LayoutSVGText {text} at (102,284) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (102.57,292.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (101,244) size 8x49 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=93.70] [y=236.00] [width=7.25] [height=49.00]
+          LayoutSVGText {text} at (95,284) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (95.32,292.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (91,244) size 11x49 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=83.19] [y=236.00] [width=10.51] [height=49.00]
+          LayoutSVGText {text} at (86,284) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (86.44,292.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (80,244) size 12x49 [fill={[type=SOLID] [color=#EE82EE] [opacity=0.30]}] [x=72.68] [y=236.00] [width=10.51] [height=49.00]
+          LayoutSVGText {text} at (75,284) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (75.93,292.00) startOffset 0 endOffset 1 width 4.00: "6"
+          LayoutSVGRect {rect} at (116,244) size 12x49 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=108.19] [y=236.00] [width=11.02] [height=49.00]
+          LayoutSVGText {text} at (111,284) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (111.70,292.00) startOffset 0 endOffset 1 width 4.00: "7"
+          LayoutSVGRect {rect} at (127,244) size 7x49 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=119.21] [y=236.00] [width=5.83] [height=49.00]
+          LayoutSVGText {text} at (120,284) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (120.13,292.00) startOffset 0 endOffset 1 width 4.00: "8"
+          LayoutSVGRect {rect} at (133,244) size 6x49 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=125.04] [y=236.00] [width=5.83] [height=49.00]
+          LayoutSVGText {text} at (125,284) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (125.96,292.00) startOffset 0 endOffset 1 width 4.00: "9"
+          LayoutSVGRect {rect} at (208,252) size 12x39 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=200.00] [y=244.00] [width=11.02] [height=39.00]
+          LayoutSVGText {text} at (203,282) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (203.51,290.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (219,252) size 6x39 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=211.02] [y=244.00] [width=5.83] [height=39.00]
+          LayoutSVGText {text} at (211,282) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (211.94,290.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (224,252) size 7x39 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=216.85] [y=244.00] [width=5.83] [height=39.00]
+          LayoutSVGText {text} at (217,282) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (217.76,290.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (258,252) size 9x39 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=250.94] [y=244.00] [width=7.25] [height=39.00]
+          LayoutSVGText {text} at (252,282) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (252.57,290.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (251,252) size 8x39 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=243.70] [y=244.00] [width=7.25] [height=39.00]
+          LayoutSVGText {text} at (245,282) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (245.32,290.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (241,252) size 11x39 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=233.19] [y=244.00] [width=10.51] [height=39.00]
+          LayoutSVGText {text} at (236,282) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (236.44,290.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (230,252) size 12x39 [fill={[type=SOLID] [color=#EE82EE] [opacity=0.30]}] [x=222.68] [y=244.00] [width=10.51] [height=39.00]
+          LayoutSVGText {text} at (225,282) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (225.93,290.00) startOffset 0 endOffset 1 width 4.00: "6"
+          LayoutSVGRect {rect} at (266,252) size 12x39 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=258.19] [y=244.00] [width=11.02] [height=39.00]
+          LayoutSVGText {text} at (261,282) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (261.70,290.00) startOffset 0 endOffset 1 width 4.00: "7"
+          LayoutSVGRect {rect} at (277,252) size 7x39 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=269.21] [y=244.00] [width=5.83] [height=39.00]
+          LayoutSVGText {text} at (270,282) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (270.13,290.00) startOffset 0 endOffset 1 width 4.00: "8"
+          LayoutSVGRect {rect} at (283,252) size 6x39 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=275.04] [y=244.00] [width=5.83] [height=39.00]
+          LayoutSVGText {text} at (275,282) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (275.96,290.00) startOffset 0 endOffset 1 width 4.00: "9"
+          LayoutSVGRect {rect} at (358,251) size 10x39 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=350.00] [y=243.00] [width=9.09] [height=39.00]
+          LayoutSVGText {text} at (352,281) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (352.55,289.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (367,251) size 5x39 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=359.09] [y=243.00] [width=4.86] [height=39.00]
+          LayoutSVGText {text} at (359,281) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (359.52,289.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (371,251) size 6x39 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=363.95] [y=243.00] [width=4.86] [height=39.00]
+          LayoutSVGText {text} at (364,281) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (364.38,289.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (405,251) size 8x39 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=397.08] [y=243.00] [width=7.25] [height=39.00]
+          LayoutSVGText {text} at (398,281) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (398.71,289.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (397,251) size 9x39 [fill={[type=SOLID] [color=#0000FF] [opacity=0.30]}] [x=389.84] [y=243.00] [width=7.25] [height=39.00]
+          LayoutSVGText {text} at (391,281) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (391.46,289.00) startOffset 0 endOffset 1 width 4.00: "4"
+          LayoutSVGRect {rect} at (387,251) size 11x39 [fill={[type=SOLID] [color=#4B0082] [opacity=0.30]}] [x=379.33] [y=243.00] [width=10.51] [height=39.00]
+          LayoutSVGText {text} at (382,281) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (382.58,289.00) startOffset 0 endOffset 1 width 4.00: "5"
+          LayoutSVGRect {rect} at (376,251) size 12x39 [fill={[type=SOLID] [color=#EE82EE] [opacity=0.30]}] [x=368.82] [y=243.00] [width=10.51] [height=39.00]
+          LayoutSVGText {text} at (372,281) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (372.07,289.00) startOffset 0 endOffset 1 width 4.00: "6"
+          LayoutSVGRect {rect} at (412,251) size 10x39 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=404.33] [y=243.00] [width=9.09] [height=39.00]
+          LayoutSVGText {text} at (406,281) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (406.87,289.00) startOffset 0 endOffset 1 width 4.00: "7"
+          LayoutSVGRect {rect} at (421,251) size 6x39 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=413.42] [y=243.00] [width=4.86] [height=39.00]
+          LayoutSVGText {text} at (413,281) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (413.85,289.00) startOffset 0 endOffset 1 width 4.00: "8"
+          LayoutSVGRect {rect} at (426,251) size 6x39 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=418.28] [y=243.00] [width=4.86] [height=39.00]
+          LayoutSVGText {text} at (418,281) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (418.71,289.00) startOffset 0 endOffset 1 width 4.00: "9"
+          LayoutSVGRect {rect} at (58,319) size 6x49 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=50.00] [y=311.00] [width=5.23] [height=49.00]
+          LayoutSVGText {text} at (50,359) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (50.61,367.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (63,319) size 27x49 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=55.23] [y=311.00] [width=26.25] [height=49.00]
+          LayoutSVGText {text} at (66,359) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (66.35,367.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (89,319) size 6x49 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=81.48] [y=311.00] [width=4.86] [height=49.00]
+          LayoutSVGText {text} at (81,359) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (81.91,367.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (94,319) size 6x49 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=86.34] [y=311.00] [width=4.86] [height=49.00]
+          LayoutSVGText {text} at (86,359) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (86.77,367.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (208,327) size 5x39 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=200.00] [y=319.00] [width=4.38] [height=39.00]
+          LayoutSVGText {text} at (200,357) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (200.19,365.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (212,327) size 27x39 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=204.38] [y=319.00] [width=26.25] [height=39.00]
+          LayoutSVGText {text} at (215,357) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (215.50,365.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (238,327) size 6x39 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=230.63] [y=319.00] [width=4.86] [height=39.00]
+          LayoutSVGText {text} at (231,357) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (231.06,365.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (243,327) size 6x39 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=235.49] [y=319.00] [width=4.86] [height=39.00]
+          LayoutSVGText {text} at (235,357) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (235.92,365.00) startOffset 0 endOffset 1 width 4.00: "3"
+          LayoutSVGRect {rect} at (358,326) size 5x39 [fill={[type=SOLID] [color=#FF0000] [opacity=0.30]}] [x=350.00] [y=318.00] [width=4.86] [height=39.00]
+          LayoutSVGText {text} at (350,356) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (350.43,364.00) startOffset 0 endOffset 1 width 4.00: "0"
+          LayoutSVGRect {rect} at (362,326) size 28x39 [fill={[type=SOLID] [color=#FFA500] [opacity=0.30]}] [x=354.86] [y=318.00] [width=26.25] [height=39.00]
+          LayoutSVGText {text} at (365,356) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (365.99,364.00) startOffset 0 endOffset 1 width 4.00: "1"
+          LayoutSVGRect {rect} at (389,326) size 4x39 [fill={[type=SOLID] [color=#FFFF00] [opacity=0.30]}] [x=381.11] [y=318.00] [width=3.89] [height=39.00]
+          LayoutSVGText {text} at (381,356) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (381.06,364.00) startOffset 0 endOffset 1 width 4.00: "2"
+          LayoutSVGRect {rect} at (393,326) size 4x39 [fill={[type=SOLID] [color=#008000] [opacity=0.30]}] [x=385.00] [y=318.00] [width=3.89] [height=39.00]
+          LayoutSVGText {text} at (384,356) size 5x10 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 4x10
+              chunk 1 (middle anchor) text run 1 at (384.94,364.00) startOffset 0 endOffset 1 width 4.00: "3"
+        LayoutSVGContainer {g} at (53,19) size 384x349
+          LayoutSVGText {text} at (50,11) size 49x49 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 49x49
+              chunk 1 text run 1 at (50.00,50.00) startOffset 0 endOffset 6 width 48.57: "ab\x{30C}c\x{30C}\x{30C}"
+          LayoutSVGText {text} at (200,17) size 49x41 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 49x41
+              chunk 1 text run 1 at (200.00,50.00) startOffset 0 endOffset 6 width 48.57: "ab\x{30C}c\x{30C}\x{30C}"
+          LayoutSVGText {text} at (350,18) size 57x39 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 57x39
+              chunk 1 text run 1 at (350.00,50.00) startOffset 0 endOffset 6 width 56.43: "ab\x{30C}c\x{30C}\x{30C}"
+          LayoutSVGText {text} at (49,86) size 51x49 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 51x49
+              chunk 1 text run 1 at (49.06,125.00) startOffset 0 endOffset 3 width 15.53: "c\x{30C}\x{30C}"
+              chunk 1 text run 1 at (64.59,125.00) startOffset 0 endOffset 1 width 0.00 RTL: "\x{200F}"
+              chunk 1 text run 1 at (64.59,125.00) startOffset 0 endOffset 2 width 17.50: "b\x{30C}"
+              chunk 1 text run 1 at (82.09,125.00) startOffset 0 endOffset 1 width 0.00 RTL: "\x{200F}"
+              chunk 1 text run 1 at (82.09,125.00) startOffset 0 endOffset 1 width 17.91: "a"
+              chunk 1 text run 1 at (100.00,125.00) startOffset 0 endOffset 1 width 0.00 RTL: "\x{200F}"
+          LayoutSVGText {text} at (201,94) size 49x39 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 49x39
+              chunk 1 text run 1 at (201.43,125.00) startOffset 0 endOffset 3 width 15.53: "c\x{30C}\x{30C}"
+              chunk 1 text run 1 at (216.97,125.00) startOffset 0 endOffset 1 width 0.00 RTL: "\x{200F}"
+              chunk 1 text run 1 at (216.97,125.00) startOffset 0 endOffset 2 width 17.50: "b\x{30C}"
+              chunk 1 text run 1 at (234.47,125.00) startOffset 0 endOffset 1 width 0.00 RTL: "\x{200F}"
+              chunk 1 text run 1 at (234.47,125.00) startOffset 0 endOffset 1 width 15.53: "a"
+              chunk 1 text run 1 at (250.00,125.00) startOffset 0 endOffset 1 width 0.00 RTL: "\x{200F}"
+          LayoutSVGText {text} at (343,93) size 57x39 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 57x39
+              chunk 1 text run 1 at (343.57,125.00) startOffset 0 endOffset 3 width 17.50: "c\x{30C}\x{30C}"
+              chunk 1 text run 1 at (361.07,125.00) startOffset 0 endOffset 1 width 0.00 RTL: "\x{200F}"
+              chunk 1 text run 1 at (361.07,125.00) startOffset 0 endOffset 2 width 19.47: "b\x{30C}"
+              chunk 1 text run 1 at (380.53,125.00) startOffset 0 endOffset 1 width 0.00 RTL: "\x{200F}"
+              chunk 1 text run 1 at (380.53,125.00) startOffset 0 endOffset 1 width 19.47: "a"
+              chunk 1 text run 1 at (400.00,125.00) startOffset 0 endOffset 1 width 0.00 RTL: "\x{200F}"
+          LayoutSVGText {text} at (50,161) size 70x49 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 70x49
+              chunk 1 text run 1 at (50.00,200.00) startOffset 0 endOffset 9 width 64.24: "fi\x{30C} ffi\x{30C}\x{30C}"
+          LayoutSVGText {text} at (200,169) size 68x39 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 68x39
+              chunk 1 text run 1 at (200.00,200.00) startOffset 0 endOffset 9 width 62.53: "fi\x{30C} ffi\x{30C}\x{30C}"
+          LayoutSVGText {text} at (350,168) size 60x39 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 60x39
+              chunk 1 text run 1 at (350.00,200.00) startOffset 0 endOffset 9 width 53.82: "fi\x{30C} ffi\x{30C}\x{30C}"
+          LayoutSVGText {text} at (50,236) size 86x49 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 86x49
+              chunk 1 text run 1 at (50.00,275.00) startOffset 0 endOffset 3 width 22.68: "ff\x{30C}"
+              chunk 1 text run 1 at (72.68,275.00) startOffset 0 endOffset 4 width 35.51 RTL: "\x{640}\x{640}\x{644}\x{627}"
+              chunk 1 text run 1 at (108.19,275.00) startOffset 0 endOffset 3 width 22.68: "ff\x{30C}"
+          LayoutSVGText {text} at (200,244) size 86x39 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 86x39
+              chunk 1 text run 1 at (200.00,275.00) startOffset 0 endOffset 3 width 22.68: "ff\x{30C}"
+              chunk 1 text run 1 at (222.68,275.00) startOffset 0 endOffset 4 width 35.51 RTL: "\x{640}\x{640}\x{644}\x{627}"
+              chunk 1 text run 1 at (258.19,275.00) startOffset 0 endOffset 3 width 22.68: "ff\x{30C}"
+          LayoutSVGText {text} at (350,243) size 79x39 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 79x39
+              chunk 1 text run 1 at (350.00,275.00) startOffset 0 endOffset 3 width 18.82: "ff\x{30C}"
+              chunk 1 text run 1 at (368.82,275.00) startOffset 0 endOffset 4 width 35.51 RTL: "\x{640}\x{640}\x{644}\x{627}"
+              chunk 1 text run 1 at (404.33,275.00) startOffset 0 endOffset 3 width 18.82: "ff\x{30C}"
+          LayoutSVGText {text} at (45,311) size 52x49 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 52x49
+              chunk 1 text run 1 at (50.00,350.00) startOffset 0 endOffset 1 width 5.23: "\x{30C}"
+              chunk 1 text run 1 at (55.23,350.00) startOffset 0 endOffset 1 width 26.25 RTL: "\x{FDB0}"
+              chunk 1 text run 1 at (81.48,350.00) startOffset 0 endOffset 2 width 9.72: "i\x{333}"
+          LayoutSVGText {text} at (195,319) size 51x39 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 51x39
+              chunk 1 text run 1 at (200.00,350.00) startOffset 0 endOffset 1 width 4.38: "\x{30C}"
+              chunk 1 text run 1 at (204.38,350.00) startOffset 0 endOffset 1 width 26.25 RTL: "\x{FDB0}"
+              chunk 1 text run 1 at (230.63,350.00) startOffset 0 endOffset 2 width 9.72: "i\x{333}"
+          LayoutSVGText {text} at (344,318) size 51x40 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,0) size 50x40
+              chunk 1 text run 1 at (350.00,350.00) startOffset 0 endOffset 1 width 4.86: "\x{30C}"
+              chunk 1 text run 1 at (354.86,350.00) startOffset 0 endOffset 1 width 26.25 RTL: "\x{FDB0}"
+              chunk 1 text run 1 at (381.11,350.00) startOffset 0 endOffset 2 width 7.78: "i\x{333}"
+      LayoutText {#text} at (0,0) size 0x0
+      LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/Source/bindings/scripts/v8_dictionary.py b/third_party/WebKit/Source/bindings/scripts/v8_dictionary.py
index dde7e1c..a6abb31 100644
--- a/third_party/WebKit/Source/bindings/scripts/v8_dictionary.py
+++ b/third_party/WebKit/Source/bindings/scripts/v8_dictionary.py
@@ -53,13 +53,21 @@
 def dictionary_context(dictionary, interfaces_info):
     includes.clear()
     includes.update(DICTIONARY_CPP_INCLUDES)
+
+    members = [member_context(dictionary, member)
+               for member in sorted(dictionary.members,
+                                    key=operator.attrgetter('name'))]
+
+    for member in members:
+        if member['runtime_enabled_function']:
+            includes.add('platform/RuntimeEnabledFeatures.h')
+            break
+
     cpp_class = v8_utilities.cpp_name(dictionary)
     context = {
         'cpp_class': cpp_class,
         'header_includes': set(DICTIONARY_H_INCLUDES),
-        'members': [member_context(dictionary, member)
-                    for member in sorted(dictionary.members,
-                                         key=operator.attrgetter('name'))],
+        'members': members,
         'required_member_names': sorted([member.name
                                          for member in dictionary.members
                                          if member.is_required]),
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestDictionary.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestDictionary.cpp
index 99c61ae..6693b2c 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestDictionary.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestDictionary.cpp
@@ -21,6 +21,7 @@
 #include "bindings/core/v8/V8Uint8Array.h"
 #include "core/dom/FlexibleArrayBufferView.h"
 #include "core/frame/Deprecation.h"
+#include "platform/RuntimeEnabledFeatures.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/core/dom/Node.h b/third_party/WebKit/Source/core/dom/Node.h
index b3422f8..45c2960 100644
--- a/third_party/WebKit/Source/core/dom/Node.h
+++ b/third_party/WebKit/Source/core/dom/Node.h
@@ -233,10 +233,8 @@
     virtual PassRefPtrWillBeRawPtr<Node> cloneNode(bool deep) = 0;
     void normalize();
 
-    // TODO(yosin): Once we drop |Node.prototype.isSameNode()|, we should
-    // get rid of |isSameNodeDeprecated()|.
-    bool isSameNodeDeprecated(Node* other) const { return this == other; }
     bool isEqualNode(Node*) const;
+    bool isSameNode(Node* other) const { return this == other; }
     bool isDefaultNamespace(const AtomicString& namespaceURI) const;
     const AtomicString& lookupPrefix(const AtomicString& namespaceURI) const;
     const AtomicString& lookupNamespaceURI(const String& prefix) const;
diff --git a/third_party/WebKit/Source/core/dom/Node.idl b/third_party/WebKit/Source/core/dom/Node.idl
index 12251c59..b16f9d2 100644
--- a/third_party/WebKit/Source/core/dom/Node.idl
+++ b/third_party/WebKit/Source/core/dom/Node.idl
@@ -59,7 +59,8 @@
     [CustomElementCallbacks] void normalize();
 
     [NewObject, CustomElementCallbacks] Node cloneNode(optional boolean deep = false);
-    boolean isEqualNode(Node? node);
+    boolean isEqualNode(Node? otherNode);
+    boolean isSameNode(Node? otherNode); // historical alias of ===
 
     const unsigned short DOCUMENT_POSITION_DISCONNECTED = 0x01;
     const unsigned short DOCUMENT_POSITION_PRECEDING = 0x02;
@@ -78,8 +79,4 @@
     [CustomElementCallbacks, PerWorldBindings, RaisesException] Node appendChild(Node node);
     [CustomElementCallbacks, PerWorldBindings, RaisesException] Node replaceChild(Node node, Node child);
     [CustomElementCallbacks, RaisesException] Node removeChild(Node child);
-
-    // FIXME: isSameNode has been removed from the spec:
-    // https://www.w3.org/Bugs/Public/show_bug.cgi?id=27424
-    [MeasureAs=NodeIsSameNode, ImplementedAs=isSameNodeDeprecated] boolean isSameNode(Node? other);
 };
diff --git a/third_party/WebKit/Source/core/dom/QualifiedName.cpp b/third_party/WebKit/Source/core/dom/QualifiedName.cpp
index 20917e11a..18b42cc 100644
--- a/third_party/WebKit/Source/core/dom/QualifiedName.cpp
+++ b/third_party/WebKit/Source/core/dom/QualifiedName.cpp
@@ -70,14 +70,14 @@
 QualifiedName::QualifiedName(const AtomicString& p, const AtomicString& l, const AtomicString& n)
 {
     QualifiedNameData data = { { p.impl(), l.impl(), n.isEmpty() ? nullAtom.impl() : n.impl() }, false };
-    QualifiedNameCache::AddResult addResult = qualifiedNameCache().add<QNameComponentsTranslator>(data);
+    QualifiedNameCache::AddResult addResult = qualifiedNameCache().addWithTranslator<QNameComponentsTranslator>(data);
     m_impl = addResult.isNewEntry ? adoptRef(*addResult.storedValue) : *addResult.storedValue;
 }
 
 QualifiedName::QualifiedName(const AtomicString& p, const AtomicString& l, const AtomicString& n, bool isStatic)
 {
     QualifiedNameData data = { { p.impl(), l.impl(), n.impl() }, isStatic };
-    QualifiedNameCache::AddResult addResult = qualifiedNameCache().add<QNameComponentsTranslator>(data);
+    QualifiedNameCache::AddResult addResult = qualifiedNameCache().addWithTranslator<QNameComponentsTranslator>(data);
     m_impl = addResult.isNewEntry ? adoptRef(*addResult.storedValue) : *addResult.storedValue;
 }
 
diff --git a/third_party/WebKit/Source/core/editing/commands/EditorCommand.cpp b/third_party/WebKit/Source/core/editing/commands/EditorCommand.cpp
index 046db31..c9613857 100644
--- a/third_party/WebKit/Source/core/editing/commands/EditorCommand.cpp
+++ b/third_party/WebKit/Source/core/editing/commands/EditorCommand.cpp
@@ -1512,9 +1512,9 @@
         { "DeleteWordBackward", {20, executeDeleteWordBackward, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
         { "DeleteWordForward", {21, executeDeleteWordForward, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
         { "FindString", {22, executeFindString, supported, enabled, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
-        { "FontName", {23, executeFontName, supported, enabledInEditableText, stateNone, valueFontName, notTextInsertion, doNotAllowExecutionWhenDisabled } },
-        { "FontSize", {24, executeFontSize, supported, enabledInEditableText, stateNone, valueFontSize, notTextInsertion, doNotAllowExecutionWhenDisabled } },
-        { "FontSizeDelta", {25, executeFontSizeDelta, supported, enabledInEditableText, stateNone, valueFontSizeDelta, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+        { "FontName", {23, executeFontName, supported, enabledInRichlyEditableText, stateNone, valueFontName, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+        { "FontSize", {24, executeFontSize, supported, enabledInRichlyEditableText, stateNone, valueFontSize, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+        { "FontSizeDelta", {25, executeFontSizeDelta, supported, enabledInRichlyEditableText, stateNone, valueFontSizeDelta, notTextInsertion, doNotAllowExecutionWhenDisabled } },
         { "ForeColor", {26, executeForeColor, supported, enabledInRichlyEditableText, stateNone, valueForeColor, notTextInsertion, doNotAllowExecutionWhenDisabled } },
         { "FormatBlock", {27, executeFormatBlock, supported, enabledInRichlyEditableText, stateNone, valueFormatBlock, notTextInsertion, doNotAllowExecutionWhenDisabled } },
         { "ForwardDelete", {28, executeForwardDelete, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
diff --git a/third_party/WebKit/Source/core/frame/UseCounter.h b/third_party/WebKit/Source/core/frame/UseCounter.h
index 42bdd408..0d3fffc9 100644
--- a/third_party/WebKit/Source/core/frame/UseCounter.h
+++ b/third_party/WebKit/Source/core/frame/UseCounter.h
@@ -142,7 +142,6 @@
         DocumentXMLEncoding = 115, // Removed from DOM4.
         DocumentXMLStandalone = 116, // Removed from DOM4.
         DocumentXMLVersion = 117, // Removed from DOM4.
-        NodeIsSameNode = 118, // Removed from DOM4.
         NavigatorProductSub = 123,
         NavigatorVendor = 124,
         NavigatorVendorSub = 125,
diff --git a/third_party/WebKit/Source/core/inspector/InspectorDebuggerAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorDebuggerAgent.cpp
index 0b1114c..b5867e7d 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorDebuggerAgent.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorDebuggerAgent.cpp
@@ -241,10 +241,9 @@
 void InspectorDebuggerAgent::setVariableValue(ErrorString* errorString, int inScopeNumber,
     const String16& inVariableName,
     PassOwnPtr<protocol::Runtime::CallArgument> inNewValue,
-    const Maybe<String16>& inCallFrameId,
-    const Maybe<String16>& inFunctionObjectId)
+    const String16& inCallFrameId)
 {
-    m_v8DebuggerAgent->setVariableValue(errorString, inScopeNumber, inVariableName, inNewValue, inCallFrameId, inFunctionObjectId);
+    m_v8DebuggerAgent->setVariableValue(errorString, inScopeNumber, inVariableName, inNewValue, inCallFrameId);
 }
 
 void InspectorDebuggerAgent::getBacktrace(ErrorString* errorString,
diff --git a/third_party/WebKit/Source/core/inspector/InspectorDebuggerAgent.h b/third_party/WebKit/Source/core/inspector/InspectorDebuggerAgent.h
index 3353951..a095471 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorDebuggerAgent.h
+++ b/third_party/WebKit/Source/core/inspector/InspectorDebuggerAgent.h
@@ -70,7 +70,7 @@
     void getCollectionEntries(ErrorString*, const String16& objectId, OwnPtr<protocol::Array<protocol::Debugger::CollectionEntry>>* entries) override;
     void setPauseOnExceptions(ErrorString*, const String16& state) override;
     void evaluateOnCallFrame(ErrorString*, const String16& callFrameId, const String16& expression, const Maybe<String16>& objectGroup, const Maybe<bool>& includeCommandLineAPI, const Maybe<bool>& doNotPauseOnExceptionsAndMuteConsole, const Maybe<bool>& returnByValue, const Maybe<bool>& generatePreview, OwnPtr<protocol::Runtime::RemoteObject>* result, Maybe<bool>* wasThrown, Maybe<protocol::Runtime::ExceptionDetails>*) override;
-    void setVariableValue(ErrorString*, int scopeNumber, const String16& variableName, PassOwnPtr<protocol::Runtime::CallArgument> newValue, const Maybe<String16>& callFrameId, const Maybe<String16>& functionObjectId) override;
+    void setVariableValue(ErrorString*, int scopeNumber, const String16& variableName, PassOwnPtr<protocol::Runtime::CallArgument> newValue, const String16& callFrameId) override;
     void getBacktrace(ErrorString*, OwnPtr<protocol::Array<protocol::Debugger::CallFrame>>* callFrames, Maybe<protocol::Runtime::StackTrace>* asyncStackTrace) override;
     void setAsyncCallStackDepth(ErrorString*, int maxDepth) override;
     void enablePromiseTracker(ErrorString*, const Maybe<bool>& captureStacks) override;
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlock.h b/third_party/WebKit/Source/core/layout/LayoutBlock.h
index 69d5271..9f6c1833 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBlock.h
+++ b/third_party/WebKit/Source/core/layout/LayoutBlock.h
@@ -316,7 +316,6 @@
 
     // FIXME-BLOCKFLOW: Remove virtualization when all callers have moved to LayoutBlockFlow
     virtual void paintFloats(const PaintInfo&, const LayoutPoint&) const { }
-    virtual void paintSelection(const PaintInfo&, const LayoutPoint&) const { }
 
 protected:
     virtual void adjustInlineDirectionLineBounds(unsigned /* expansionOpportunityCount */, LayoutUnit& /* logicalLeft */, LayoutUnit& /* logicalWidth */) const { }
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
index 438077b..fc16068 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
@@ -2678,14 +2678,6 @@
     ASSERT_NOT_REACHED();
 }
 
-IntRect alignSelectionRectToDevicePixels(LayoutRect& rect)
-{
-    LayoutUnit roundedX = LayoutUnit(rect.x().round());
-    return IntRect(roundedX, rect.y().round(),
-        (rect.maxX() - roundedX).round(),
-        snapSizeToPixel(rect.height(), rect.y()));
-}
-
 bool LayoutBlockFlow::allowsPaginationStrut() const
 {
     // The block needs to be contained by a LayoutBlockFlow (and not by e.g. a flexbox, grid, or a
diff --git a/third_party/WebKit/Source/core/layout/LayoutBox.cpp b/third_party/WebKit/Source/core/layout/LayoutBox.cpp
index 19a44fa5..eb0e47c 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBox.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBox.cpp
@@ -553,10 +553,8 @@
                 if (ownerElement && ownerElement->layoutObject()) {
                     if (frameView->safeToPropagateScrollToParent()) {
                         parentBox = ownerElement->layoutObject()->enclosingBox();
-                        // FIXME: This doesn't correctly convert the rect to
-                        // absolute coordinates in the parent.
-                        newRect.setX(rect.x() - frameView->scrollX() + frameView->x());
-                        newRect.setY(rect.y() - frameView->scrollY() + frameView->y());
+                        LayoutView* parentView = ownerElement->layoutObject()->view();
+                        newRect = enclosingLayoutRect(view()->localToAncestorQuad(FloatRect(rect), parentView, UseTransforms | TraverseDocumentBoundaries).boundingBox());
                     } else {
                         parentBox = nullptr;
                     }
@@ -3500,7 +3498,7 @@
         || (child->style()->isFlippedBlocksWritingMode() != containerBlock->style()->isFlippedBlocksWritingMode() && child->isHorizontalWritingMode() == containerBlock->isHorizontalWritingMode()))
         logicalTopPos = containerLogicalHeight - logicalHeightValue - logicalTopPos;
 
-    // Our offset is from the logical bottom edge in a flipped environment, e.g., right for vertical-rl and bottom for horizontal-bt.
+    // Our offset is from the logical bottom edge in a flipped environment, e.g., right for vertical-rl.
     if (containerBlock->style()->isFlippedBlocksWritingMode() && child->isHorizontalWritingMode() == containerBlock->isHorizontalWritingMode()) {
         if (child->isHorizontalWritingMode())
             logicalTopPos += containerBlock->borderBottom();
@@ -4076,9 +4074,9 @@
     // For overflow clip objects, we don't want to propagate overflow into unreachable areas.
     LayoutRect overflowRect(rect);
     if (hasOverflowClip() || isLayoutView()) {
-        // Overflow is in the block's coordinate space and thus is flipped for horizontal-bt and vertical-rl
-        // writing modes.  At this stage that is actually a simplification, since we can treat horizontal-tb/bt as the same
-        // and vertical-lr/rl as the same.
+        // Overflow is in the block's coordinate space and thus is flipped for vertical-rl writing
+        // mode.  At this stage that is actually a simplification, since we can treat vertical-lr/rl
+        // as the same.
         bool hasTopOverflow = !style()->isLeftToRightDirection() && !isHorizontalWritingMode();
         bool hasLeftOverflow = !style()->isLeftToRightDirection() && isHorizontalWritingMode();
         if (isFlexibleBox() && style()->isReverseFlexDirection()) {
@@ -4342,10 +4340,10 @@
 {
     // Because of the special coordinate system used for overflow rectangles and many other
     // rectangles (not quite logical, not quite physical), we need to flip the block progression
-    // coordinate in vertical-rl and horizontal-bt writing modes. In other words, the rectangle
-    // returned is physical, except for the block direction progression coordinate (y in horizontal
-    // writing modes, x in vertical writing modes), which is always "logical top". Apart from the
-    // flipping, this method does the same as clientBoxRect().
+    // coordinate in vertical-rl writing mode. In other words, the rectangle returned is physical,
+    // except for the block direction progression coordinate (x in vertical writing mode), which is
+    // always "logical top". Apart from the flipping, this method does the same thing as
+    // clientBoxRect().
 
     const int scrollBarWidth = verticalScrollbarWidth();
     const int scrollBarHeight = horizontalScrollbarHeight();
@@ -4356,10 +4354,10 @@
     LayoutRect rect(left, top, size().width() - left - right, size().height() - top - bottom);
     flipForWritingMode(rect);
     // Subtract space occupied by scrollbars. Order is important here: first flip, then subtract
-    // scrollbars. This may seem backwards and weird, since one would think that a horizontal
-    // scrollbar at the physical bottom in horizontal-bt ought to be at the logical top (physical
-    // bottom), between the logical top (physical bottom) border and the logical top (physical
-    // bottom) padding. But this is how the rest of the code expects us to behave. This is highly
+    // scrollbars. This may seem backwards and weird, since one would think that a vertical
+    // scrollbar at the physical right in vertical-rl ought to be at the logical left (physical
+    // right), between the logical left (physical right) border and the logical left (physical
+    // right) padding. But this is how the rest of the code expects us to behave. This is highly
     // related to https://bugs.webkit.org/show_bug.cgi?id=76129
     // FIXME: when the above mentioned bug is fixed, it should hopefully be possible to call
     // clientBoxRect() or paddingBoxRect() in this method, rather than fiddling with the edges on
diff --git a/third_party/WebKit/Source/core/layout/LayoutBox.h b/third_party/WebKit/Source/core/layout/LayoutBox.h
index f3c2703..441d169 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBox.h
+++ b/third_party/WebKit/Source/core/layout/LayoutBox.h
@@ -353,10 +353,11 @@
 
     bool canResize() const;
 
-    // Visual and layout overflow are in the coordinate space of the box.  This means that they aren't purely physical directions.
-    // For horizontal-tb and vertical-lr they will match physical directions, but for horizontal-bt and vertical-rl, the top/bottom and left/right
-    // respectively are flipped when compared to their physical counterparts.  For example minX is on the left in vertical-lr,
-    // but it is on the right in vertical-rl.
+    // Visual and layout overflow are in the coordinate space of the box.  This means that they
+    // aren't purely physical directions. For horizontal-tb and vertical-lr they will match physical
+    // directions, but for vertical-rl, the left/right are flipped when compared to their physical
+    // counterparts.  For example minX is on the left in vertical-lr, but it is on the right in
+    // vertical-rl.
     LayoutRect noOverflowRect() const;
     LayoutRect layoutOverflowRect() const { return m_overflow ? m_overflow->layoutOverflowRect() : noOverflowRect(); }
     IntRect pixelSnappedLayoutOverflowRect() const { return pixelSnappedIntRect(layoutOverflowRect()); }
diff --git a/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp b/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp
index 7010410..994c3a8 100644
--- a/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp
@@ -1095,18 +1095,36 @@
     return childCrossSize;
 }
 
+LayoutUnit LayoutFlexibleBox::mainSizeForPercentageResolution(const LayoutBox& child)
+{
+    // This function implements section 9.8. Definite and Indefinite Sizes, case
+    // 2) of the flexbox spec.
+    // We need to check for the flexbox to have a definite main size, and for the
+    // flex item to have a definite flex basis.
+    const Length& flexBasis = flexBasisForChild(child);
+    if (!mainAxisLengthIsDefinite(child, flexBasis))
+        return LayoutUnit(-1);
+    LayoutUnit mainSize = isColumnFlow() ? computeDefiniteLogicalHeight() : computeDefiniteLogicalWidth();
+    if (mainSize == LayoutUnit(-1))
+        return mainSize;
+
+    if (hasOrthogonalFlow(child))
+        return child.hasOverrideLogicalContentHeight() ? child.overrideLogicalContentHeight() : LayoutUnit(-1);
+    return child.hasOverrideLogicalContentWidth() ? child.overrideLogicalContentWidth() : LayoutUnit(-1);
+}
+
 LayoutUnit LayoutFlexibleBox::childLogicalHeightForPercentageResolution(const LayoutBox& child)
 {
     if (!hasOrthogonalFlow(child))
         return crossSizeForPercentageResolution(child);
-    return LayoutUnit(-1);
+    return mainSizeForPercentageResolution(child);
 }
 
 LayoutUnit LayoutFlexibleBox::childLogicalWidthForPercentageResolution(const LayoutBox& child)
 {
     if (hasOrthogonalFlow(child))
         return crossSizeForPercentageResolution(child);
-    return LayoutUnit(-1);
+    return mainSizeForPercentageResolution(child);
 }
 
 LayoutUnit LayoutFlexibleBox::adjustChildSizeForAspectRatioCrossAxisMinAndMax(const LayoutBox& child, LayoutUnit childSize)
@@ -1430,6 +1448,11 @@
         LayoutUnit childPreferredSize = childSizes[i] + mainAxisBorderAndPaddingExtentForChild(*child);
         setOverrideMainAxisSizeForChild(*child, childPreferredSize);
         if (childPreferredSize != mainAxisExtentForChild(*child)) {
+            // We will correctly handle percentage sizing even without re-laying out here, because
+            // if our size was already correct, then percentage resolution was also correct due
+            // to the way percentage sizing is defined by flexbox (ie. it requires a definite flex basis)
+            // TODO(cbiesinger): When flex-basis is used instead of width/height, this is not the case. That
+            // problem is not limited to percentages. See http://crbug.com/531656#c11
             child->setChildNeedsLayout(MarkOnlyThis);
         } else {
             // To avoid double applying margin changes in updateAutoMarginsInCrossAxis, we reset the margins here.
diff --git a/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.h b/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.h
index 5057496..84b00869 100644
--- a/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.h
+++ b/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.h
@@ -65,6 +65,7 @@
     LayoutUnit computeDefiniteLogicalHeight();
 
     LayoutUnit crossSizeForPercentageResolution(const LayoutBox& child);
+    LayoutUnit mainSizeForPercentageResolution(const LayoutBox& child);
     LayoutUnit childLogicalHeightForPercentageResolution(const LayoutBox& child);
     LayoutUnit childLogicalWidthForPercentageResolution(const LayoutBox& child);
 
diff --git a/third_party/WebKit/Source/core/layout/line/InlineFlowBox.cpp b/third_party/WebKit/Source/core/layout/line/InlineFlowBox.cpp
index 26508e0..75506c8 100644
--- a/third_party/WebKit/Source/core/layout/line/InlineFlowBox.cpp
+++ b/third_party/WebKit/Source/core/layout/line/InlineFlowBox.cpp
@@ -784,7 +784,7 @@
         return;
 
     // Similar to how glyph overflow works, if our lines are flipped, then it's actually the opposite border that applies, since
-    // the line is "upside down" in terms of block coordinates. vertical-rl and horizontal-bt are the flipped line modes.
+    // the line is "upside down" in terms of block coordinates. vertical-rl is the flipped line mode.
     LayoutRectOutsets logicalOutsets = style.borderImageOutsets().logicalOutsetsWithFlippedLines(style.getWritingMode());
 
     if (!includeLogicalLeftEdge())
diff --git a/third_party/WebKit/Source/core/layout/line/InlineFlowBox.h b/third_party/WebKit/Source/core/layout/line/InlineFlowBox.h
index 9f50366..9cae6501 100644
--- a/third_party/WebKit/Source/core/layout/line/InlineFlowBox.h
+++ b/third_party/WebKit/Source/core/layout/line/InlineFlowBox.h
@@ -202,9 +202,11 @@
     void checkConsistency() const;
     void setHasBadChildList();
 
-    // Line visual and layout overflow are in the coordinate space of the block.  This means that they aren't purely physical directions.
-    // For horizontal-tb and vertical-lr they will match physical directions, but for horizontal-bt and vertical-rl, the top/bottom and left/right
-    // respectively are flipped when compared to their physical counterparts.  For example minX is on the left in vertical-lr, but it is on the right in vertical-rl.
+    // Line visual and layout overflow are in the coordinate space of the block.  This means that
+    // they aren't purely physical directions. For horizontal-tb and vertical-lr they will match
+    // physical directions, but for vertical-rl, the left/right respectively are flipped when
+    // compared to their physical counterparts.  For example minX is on the left in vertical-lr, but
+    // it is on the right in vertical-rl.
     LayoutRect layoutOverflowRect(LayoutUnit lineTop, LayoutUnit lineBottom) const
     {
         return m_overflow ? m_overflow->layoutOverflowRect() : frameRectIncludingLineHeight(lineTop, lineBottom);
diff --git a/third_party/WebKit/Source/core/layout/line/InlineTextBox.h b/third_party/WebKit/Source/core/layout/line/InlineTextBox.h
index 005a20b..60e937e 100644
--- a/third_party/WebKit/Source/core/layout/line/InlineTextBox.h
+++ b/third_party/WebKit/Source/core/layout/line/InlineTextBox.h
@@ -184,8 +184,6 @@
 
 DEFINE_INLINE_BOX_TYPE_CASTS(InlineTextBox);
 
-void alignSelectionRectToDevicePixels(LayoutRect&);
-
 } // namespace blink
 
 #endif // InlineTextBox_h
diff --git a/third_party/WebKit/Source/core/paint/BlockFlowPainter.h b/third_party/WebKit/Source/core/paint/BlockFlowPainter.h
index 7d76d23a..47c76af 100644
--- a/third_party/WebKit/Source/core/paint/BlockFlowPainter.h
+++ b/third_party/WebKit/Source/core/paint/BlockFlowPainter.h
@@ -18,7 +18,6 @@
 public:
     BlockFlowPainter(const LayoutBlockFlow& layoutBlockFlow) : m_layoutBlockFlow(layoutBlockFlow) { }
     void paintFloats(const PaintInfo&, const LayoutPoint&);
-    void paintSelection(const PaintInfo&, const LayoutPoint&);
 private:
     const LayoutBlockFlow& m_layoutBlockFlow;
 };
diff --git a/third_party/WebKit/Source/core/paint/BlockPainter.cpp b/third_party/WebKit/Source/core/paint/BlockPainter.cpp
index 1a2509c..6f79e75f 100644
--- a/third_party/WebKit/Source/core/paint/BlockPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/BlockPainter.cpp
@@ -183,9 +183,6 @@
 
         paintContents(contentsPaintInfo, paintOffset);
 
-        if (paintPhase == PaintPhaseForeground && !paintInfo.isPrinting())
-            m_layoutBlock.paintSelection(contentsPaintInfo, paintOffset); // Fill in gaps in selection on lines and between blocks.
-
         if (paintPhase == PaintPhaseFloat || paintPhase == PaintPhaseSelection || paintPhase == PaintPhaseTextClip)
             m_layoutBlock.paintFloats(contentsPaintInfo, paintOffset);
     }
diff --git a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp
index 20b4402..e19a8a76 100644
--- a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp
@@ -107,7 +107,6 @@
 
     const LayoutBoxModelObject& boxModelObject = toLayoutBoxModelObject(object);
 
-    // TODO(trchen): There is some insanity going on with tables. Double check results.
     switch (object.styleRef().position()) {
     case StaticPosition:
         break;
@@ -130,8 +129,17 @@
     default:
         ASSERT_NOT_REACHED();
     }
-    if (boxModelObject.isBox())
+    if (boxModelObject.isBox()) {
         context.paintOffset += toLayoutBox(boxModelObject).locationOffset();
+        // This is a weird quirk that table cells paint as children of table rows,
+        // but their location have the row's location baked-in.
+        // Similar adjustment is done in LayoutTableCell::offsetFromContainer().
+        if (boxModelObject.isTableCell()) {
+            LayoutObject* parentRow = boxModelObject.parent();
+            ASSERT(parentRow && parentRow->isTableRow());
+            context.paintOffset -= toLayoutBox(parentRow)->locationOffset();
+        }
+    }
 }
 
 static PassRefPtr<TransformPaintPropertyNode> createPaintOffsetTranslationIfNeeded(const LayoutObject& object, PaintPropertyTreeBuilderContext& context)
diff --git a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.cpp b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.cpp
index 22eb5bdb..42aac18 100644
--- a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.cpp
@@ -679,4 +679,44 @@
     EXPECT_EQ(scrollerProperties->effect(), childProperties->localBorderBoxProperties()->effect);
 }
 
+TEST_F(PaintPropertyTreeBuilderTest, TableCellLayoutLocation)
+{
+    // This test verifies that the border box space of a table cell is being correctly computed.
+    // Table cells have weird location adjustment in our layout/paint implementation.
+    setBodyInnerHTML(
+        "<style>"
+        "  body {"
+        "    margin: 0;"
+        "  }"
+        "  table {"
+        "    border-spacing: 0;"
+        "    margin: 20px;"
+        "    padding: 40px;"
+        "    border: 10px solid black;"
+        "  }"
+        "  td {"
+        "    width: 100px;"
+        "    height: 100px;"
+        "    padding: 0;"
+        "  }"
+        "  #target {"
+        "    position: relative;"
+        "    width: 100px;"
+        "    height: 100px;"
+        "  }"
+        "</style>"
+        "<table>"
+        "  <tr><td></td><td></td></tr>"
+        "  <tr><td></td><td><div id='target'></div></td></tr>"
+        "</table>"
+    );
+
+    FrameView* frameView = document().view();
+    LayoutObject& target = *document().getElementById("target")->layoutObject();
+    ObjectPaintProperties* targetProperties = target.objectPaintProperties();
+
+    EXPECT_EQ(LayoutPoint(170, 170), targetProperties->localBorderBoxProperties()->paintOffset);
+    EXPECT_EQ(frameView->scrollTranslation(), targetProperties->localBorderBoxProperties()->transform);
+}
+
 } // namespace blink
diff --git a/third_party/WebKit/Source/devtools/front_end/cm/css.js b/third_party/WebKit/Source/devtools/front_end/cm/css.js
index 2673074..91046d9 100644
--- a/third_party/WebKit/Source/devtools/front_end/cm/css.js
+++ b/third_party/WebKit/Source/devtools/front_end/cm/css.js
@@ -452,8 +452,8 @@
     "animation-direction", "animation-duration", "animation-fill-mode",
     "animation-iteration-count", "animation-name", "animation-play-state",
     "animation-timing-function", "appearance", "azimuth", "backface-visibility",
-    "background", "background-attachment", "background-clip", "background-color",
-    "background-image", "background-origin", "background-position",
+    "background", "background-attachment", "background-blend-mode", "background-clip",
+    "background-color", "background-image", "background-origin", "background-position",
     "background-repeat", "background-size", "baseline-shift", "binding",
     "bleed", "bookmark-label", "bookmark-level", "bookmark-state",
     "bookmark-target", "border", "border-bottom", "border-bottom-color",
@@ -597,11 +597,12 @@
     "capitalize", "caps-lock-indicator", "caption", "captiontext", "caret",
     "cell", "center", "checkbox", "circle", "cjk-decimal", "cjk-earthly-branch",
     "cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote",
-    "col-resize", "collapse", "column", "column-reverse", "compact", "condensed", "contain", "content",
+    "col-resize", "collapse", "color", "color-burn", "color-dodge", "column", "column-reverse",
+    "compact", "condensed", "contain", "content",
     "content-box", "context-menu", "continuous", "copy", "counter", "counters", "cover", "crop",
-    "cross", "crosshair", "currentcolor", "cursive", "cyclic", "dashed", "decimal",
+    "cross", "crosshair", "currentcolor", "cursive", "cyclic", "darken", "dashed", "decimal",
     "decimal-leading-zero", "default", "default-button", "destination-atop",
-    "destination-in", "destination-out", "destination-over", "devanagari",
+    "destination-in", "destination-out", "destination-over", "devanagari", "difference",
     "disc", "discard", "disclosure-closed", "disclosure-open", "document",
     "dot-dash", "dot-dot-dash",
     "dotted", "double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out",
@@ -612,23 +613,23 @@
     "ethiopic-halehame-gez", "ethiopic-halehame-om-et",
     "ethiopic-halehame-sid-et", "ethiopic-halehame-so-et",
     "ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et", "ethiopic-halehame-tig",
-    "ethiopic-numeric", "ew-resize", "expanded", "extends", "extra-condensed",
+    "ethiopic-numeric", "ew-resize", "exclusion", "expanded", "extends", "extra-condensed",
     "extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "flex", "flex-end", "flex-start", "footnotes",
     "forwards", "from", "geometricPrecision", "georgian", "graytext", "groove",
-    "gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hebrew",
+    "gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hard-light", "hebrew",
     "help", "hidden", "hide", "higher", "highlight", "highlighttext",
-    "hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "icon", "ignore",
+    "hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "hue", "icon", "ignore",
     "inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite",
     "infobackground", "infotext", "inherit", "initial", "inline", "inline-axis",
     "inline-block", "inline-flex", "inline-table", "inset", "inside", "intrinsic", "invert",
     "italic", "japanese-formal", "japanese-informal", "justify", "kannada",
     "katakana", "katakana-iroha", "keep-all", "khmer",
     "korean-hangul-formal", "korean-hanja-formal", "korean-hanja-informal",
-    "landscape", "lao", "large", "larger", "left", "level", "lighter",
+    "landscape", "lao", "large", "larger", "left", "level", "lighter", "lighten",
     "line-through", "linear", "linear-gradient", "lines", "list-item", "listbox", "listitem",
     "local", "logical", "loud", "lower", "lower-alpha", "lower-armenian",
     "lower-greek", "lower-hexadecimal", "lower-latin", "lower-norwegian",
-    "lower-roman", "lowercase", "ltr", "malayalam", "match", "matrix", "matrix3d",
+    "lower-roman", "lowercase", "ltr", "luminosity", "malayalam", "match", "matrix", "matrix3d",
     "media-controls-background", "media-current-time-display",
     "media-fullscreen-button", "media-mute-button", "media-play-button",
     "media-return-to-realtime-button", "media-rewind-button",
@@ -637,7 +638,7 @@
     "media-volume-slider-container", "media-volume-sliderthumb", "medium",
     "menu", "menulist", "menulist-button", "menulist-text",
     "menulist-textfield", "menutext", "message-box", "middle", "min-intrinsic",
-    "mix", "mongolian", "monospace", "move", "multiple", "myanmar", "n-resize",
+    "mix", "mongolian", "monospace", "move", "multiple", "multiply", "myanmar", "n-resize",
     "narrower", "ne-resize", "nesw-resize", "no-close-quote", "no-drop",
     "no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap",
     "ns-resize", "numbers", "numeric", "nw-resize", "nwse-resize", "oblique", "octal", "open-quote",
@@ -651,7 +652,7 @@
     "repeating-radial-gradient", "repeat-x", "repeat-y", "reset", "reverse",
     "rgb", "rgba", "ridge", "right", "rotate", "rotate3d", "rotateX", "rotateY",
     "rotateZ", "round", "row", "row-resize", "row-reverse", "rtl", "run-in", "running",
-    "s-resize", "sans-serif", "scale", "scale3d", "scaleX", "scaleY", "scaleZ",
+    "s-resize", "sans-serif", "saturation", "scale", "scale3d", "scaleX", "scaleY", "scaleZ", "screen",
     "scroll", "scrollbar", "se-resize", "searchfield",
     "searchfield-cancel-button", "searchfield-decoration",
     "searchfield-results-button", "searchfield-results-decoration",
@@ -659,7 +660,7 @@
     "simp-chinese-formal", "simp-chinese-informal", "single",
     "skew", "skewX", "skewY", "skip-white-space", "slide", "slider-horizontal",
     "slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow",
-    "small", "small-caps", "small-caption", "smaller", "solid", "somali",
+    "small", "small-caps", "small-caption", "smaller", "soft-light", "solid", "somali",
     "source-atop", "source-in", "source-out", "source-over", "space", "space-around", "space-between", "spell-out", "square",
     "square-button", "start", "static", "status-bar", "stretch", "stroke", "sub",
     "subpixel-antialiased", "super", "sw-resize", "symbolic", "symbols", "table",
@@ -821,4 +822,4 @@
     helperType: "gss"
   });
 
-});
+});
\ No newline at end of file
diff --git a/third_party/WebKit/Source/devtools/front_end/cm/javascript.js b/third_party/WebKit/Source/devtools/front_end/cm/javascript.js
index b961b890..c91910f 100644
--- a/third_party/WebKit/Source/devtools/front_end/cm/javascript.js
+++ b/third_party/WebKit/Source/devtools/front_end/cm/javascript.js
@@ -13,6 +13,11 @@
 })(function(CodeMirror) {
 "use strict";
 
+function expressionAllowed(stream, state, backUp) {
+  return /^(?:operator|sof|keyword c|case|new|[\[{}\(,;:]|=>)$/.test(state.lastType) ||
+    (state.lastType == "quasi" && /\{\s*$/.test(stream.string.slice(0, stream.pos - (backUp || 0))))
+}
+
 CodeMirror.defineMode("javascript", function(config, parserConfig) {
   var indentUnit = config.indentUnit;
   var statementIndent = parserConfig.statementIndent;
@@ -32,12 +37,12 @@
       "if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
       "return": C, "break": C, "continue": C, "new": kw("new"), "delete": C, "throw": C, "debugger": C,
       "var": kw("var"), "const": kw("var"), "let": kw("var"),
-      "async": kw("async"), "function": kw("function"), "catch": kw("catch"),
+      "function": kw("function"), "catch": kw("catch"),
       "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
       "in": operator, "typeof": operator, "instanceof": operator,
       "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom,
       "this": kw("this"), "class": kw("class"), "super": kw("atom"),
-      "await": C, "yield": C, "export": kw("export"), "import": kw("import"), "extends": C
+      "yield": C, "export": kw("export"), "import": kw("import"), "extends": C
     };
 
     // Extend the 'normal' keywords with the TypeScript language extensions
@@ -45,15 +50,20 @@
       var type = {type: "variable", style: "variable-3"};
       var tsKeywords = {
         // object-like things
-        "interface": kw("interface"),
-        "extends": kw("extends"),
-        "constructor": kw("constructor"),
+        "interface": kw("class"),
+        "implements": C,
+        "namespace": C,
+        "module": kw("module"),
+        "enum": kw("module"),
 
         // scope modifiers
-        "public": kw("public"),
-        "private": kw("private"),
-        "protected": kw("protected"),
-        "static": kw("static"),
+        "public": kw("modifier"),
+        "private": kw("modifier"),
+        "protected": kw("modifier"),
+        "abstract": kw("modifier"),
+
+        // operators
+        "as": operator,
 
         // types
         "string": type, "number": type, "boolean": type, "any": type
@@ -121,8 +131,7 @@
       } else if (stream.eat("/")) {
         stream.skipToEnd();
         return ret("comment", "comment");
-      } else if (state.lastType == "operator" || state.lastType == "keyword c" ||
-                 state.lastType == "sof" || /^[\[{}\(,;:]$/.test(state.lastType)) {
+      } else if (expressionAllowed(stream, state, 1)) {
         readRegexp(stream);
         stream.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/);
         return ret("regexp", "string-2");
@@ -356,6 +365,7 @@
     if (type == "class") return cont(pushlex("form"), className, poplex);
     if (type == "export") return cont(pushlex("stat"), afterExport, poplex);
     if (type == "import") return cont(pushlex("stat"), afterImport, poplex);
+    if (type == "module") return cont(pushlex("form"), pattern, pushlex("}"), expect("{"), block, poplex, poplex)
     return pass(pushlex("stat"), expression, expect(";"), poplex);
   }
   function expression(type) {
@@ -373,7 +383,6 @@
 
     var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma;
     if (atomicTypes.hasOwnProperty(type)) return cont(maybeop);
-    if (type == "async") return cont(expression);
     if (type == "function") return cont(functiondef, maybeop);
     if (type == "keyword c") return cont(noComma ? maybeexpressionNoComma : maybeexpression);
     if (type == "(") return cont(pushlex(")"), maybeexpression, comprehension, expect(")"), poplex, maybeop);
@@ -452,9 +461,7 @@
     if (type == "variable") {cx.marked = "property"; return cont();}
   }
   function objprop(type, value) {
-    if (type == "async") {
-      return cont(objprop);
-    } else if (type == "variable" || cx.style == "keyword") {
+    if (type == "variable" || cx.style == "keyword") {
       cx.marked = "property";
       if (value == "get" || value == "set") return cont(getterSetter);
       return cont(afterprop);
@@ -463,8 +470,12 @@
       return cont(afterprop);
     } else if (type == "jsonld-keyword") {
       return cont(afterprop);
+    } else if (type == "modifier") {
+      return cont(objprop)
     } else if (type == "[") {
       return cont(expression, expect("]"), afterprop);
+    } else if (type == "spread") {
+      return cont(expression);
     }
   }
   function getterSetter(type) {
@@ -513,6 +524,7 @@
     return pass(pattern, maybetype, maybeAssign, vardefCont);
   }
   function pattern(type, value) {
+    if (type == "modifier") return cont(pattern)
     if (type == "variable") { register(value); return cont(); }
     if (type == "spread") return cont(pattern);
     if (type == "[") return contCommasep(pattern, "]");
@@ -525,6 +537,7 @@
     }
     if (type == "variable") cx.marked = "property";
     if (type == "spread") return cont(pattern);
+    if (type == "}") return pass();
     return cont(expect(":"), pattern, maybeAssign);
   }
   function maybeAssign(_type, value) {
@@ -647,7 +660,7 @@
         lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
         localVars: parserConfig.localVars,
         context: parserConfig.localVars && {vars: parserConfig.localVars},
-        indented: 0
+        indented: basecolumn || 0
       };
       if (parserConfig.globalVars && typeof parserConfig.globalVars == "object")
         state.globalVars = parserConfig.globalVars;
@@ -703,7 +716,13 @@
 
     helperType: jsonMode ? "json" : "javascript",
     jsonldMode: jsonldMode,
-    jsonMode: jsonMode
+    jsonMode: jsonMode,
+
+    expressionAllowed: expressionAllowed,
+    skipExpression: function(state) {
+      var top = state.cc[state.cc.length - 1]
+      if (top == expression || top == expressionNoComma) state.cc.pop()
+    }
   };
 });
 
@@ -720,4 +739,4 @@
 CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true });
 CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true });
 
-});
+});
\ No newline at end of file
diff --git a/third_party/WebKit/Source/devtools/front_end/cm/xml.js b/third_party/WebKit/Source/devtools/front_end/cm/xml.js
index 786507d..a365739 100644
--- a/third_party/WebKit/Source/devtools/front_end/cm/xml.js
+++ b/third_party/WebKit/Source/devtools/front_end/cm/xml.js
@@ -11,54 +11,56 @@
 })(function(CodeMirror) {
 "use strict";
 
-CodeMirror.defineMode("xml", function(config, parserConfig) {
-  var indentUnit = config.indentUnit;
-  var multilineTagIndentFactor = parserConfig.multilineTagIndentFactor || 1;
-  var multilineTagIndentPastTag = parserConfig.multilineTagIndentPastTag;
-  if (multilineTagIndentPastTag == null) multilineTagIndentPastTag = true;
+var htmlConfig = {
+  autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true,
+                    'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true,
+                    'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true,
+                    'track': true, 'wbr': true, 'menuitem': true},
+  implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true, 'p': true,
+                     'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot': true,
+                     'th': true, 'tr': true},
+  contextGrabbers: {
+    'dd': {'dd': true, 'dt': true},
+    'dt': {'dd': true, 'dt': true},
+    'li': {'li': true},
+    'option': {'option': true, 'optgroup': true},
+    'optgroup': {'optgroup': true},
+    'p': {'address': true, 'article': true, 'aside': true, 'blockquote': true, 'dir': true,
+          'div': true, 'dl': true, 'fieldset': true, 'footer': true, 'form': true,
+          'h1': true, 'h2': true, 'h3': true, 'h4': true, 'h5': true, 'h6': true,
+          'header': true, 'hgroup': true, 'hr': true, 'menu': true, 'nav': true, 'ol': true,
+          'p': true, 'pre': true, 'section': true, 'table': true, 'ul': true},
+    'rp': {'rp': true, 'rt': true},
+    'rt': {'rp': true, 'rt': true},
+    'tbody': {'tbody': true, 'tfoot': true},
+    'td': {'td': true, 'th': true},
+    'tfoot': {'tbody': true},
+    'th': {'td': true, 'th': true},
+    'thead': {'tbody': true, 'tfoot': true},
+    'tr': {'tr': true}
+  },
+  doNotIndent: {"pre": true},
+  allowUnquoted: true,
+  allowMissing: true,
+  caseFold: true
+}
 
-  var Kludges = parserConfig.htmlMode ? {
-    autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true,
-                      'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true,
-                      'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true,
-                      'track': true, 'wbr': true},
-    implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true, 'p': true,
-                       'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot': true,
-                       'th': true, 'tr': true},
-    contextGrabbers: {
-      'dd': {'dd': true, 'dt': true},
-      'dt': {'dd': true, 'dt': true},
-      'li': {'li': true},
-      'option': {'option': true, 'optgroup': true},
-      'optgroup': {'optgroup': true},
-      'p': {'address': true, 'article': true, 'aside': true, 'blockquote': true, 'dir': true,
-            'div': true, 'dl': true, 'fieldset': true, 'footer': true, 'form': true,
-            'h1': true, 'h2': true, 'h3': true, 'h4': true, 'h5': true, 'h6': true,
-            'header': true, 'hgroup': true, 'hr': true, 'menu': true, 'nav': true, 'ol': true,
-            'p': true, 'pre': true, 'section': true, 'table': true, 'ul': true},
-      'rp': {'rp': true, 'rt': true},
-      'rt': {'rp': true, 'rt': true},
-      'tbody': {'tbody': true, 'tfoot': true},
-      'td': {'td': true, 'th': true},
-      'tfoot': {'tbody': true},
-      'th': {'td': true, 'th': true},
-      'thead': {'tbody': true, 'tfoot': true},
-      'tr': {'tr': true}
-    },
-    doNotIndent: {"pre": true},
-    allowUnquoted: true,
-    allowMissing: true,
-    caseFold: true
-  } : {
-    autoSelfClosers: {},
-    implicitlyClosed: {},
-    contextGrabbers: {},
-    doNotIndent: {},
-    allowUnquoted: false,
-    allowMissing: false,
-    caseFold: false
-  };
-  var alignCDATA = parserConfig.alignCDATA;
+var xmlConfig = {
+  autoSelfClosers: {},
+  implicitlyClosed: {},
+  contextGrabbers: {},
+  doNotIndent: {},
+  allowUnquoted: false,
+  allowMissing: false,
+  caseFold: false
+}
+
+CodeMirror.defineMode("xml", function(editorConf, config_) {
+  var indentUnit = editorConf.indentUnit
+  var config = {}
+  var defaults = config_.htmlMode ? htmlConfig : xmlConfig
+  for (var prop in defaults) config[prop] = defaults[prop]
+  for (var prop in config_) config[prop] = config_[prop]
 
   // Return variables for tokenizers
   var type, setStyle;
@@ -109,6 +111,7 @@
       return null;
     }
   }
+  inText.isInText = true;
 
   function inTag(stream, state) {
     var ch = stream.next();
@@ -187,7 +190,7 @@
     this.tagName = tagName;
     this.indent = state.indented;
     this.startOfLine = startOfLine;
-    if (Kludges.doNotIndent.hasOwnProperty(tagName) || (state.context && state.context.noIndent))
+    if (config.doNotIndent.hasOwnProperty(tagName) || (state.context && state.context.noIndent))
       this.noIndent = true;
   }
   function popContext(state) {
@@ -200,8 +203,8 @@
         return;
       }
       parentTagName = state.context.tagName;
-      if (!Kludges.contextGrabbers.hasOwnProperty(parentTagName) ||
-          !Kludges.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) {
+      if (!config.contextGrabbers.hasOwnProperty(parentTagName) ||
+          !config.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) {
         return;
       }
       popContext(state);
@@ -232,9 +235,9 @@
     if (type == "word") {
       var tagName = stream.current();
       if (state.context && state.context.tagName != tagName &&
-          Kludges.implicitlyClosed.hasOwnProperty(state.context.tagName))
+          config.implicitlyClosed.hasOwnProperty(state.context.tagName))
         popContext(state);
-      if (state.context && state.context.tagName == tagName) {
+      if ((state.context && state.context.tagName == tagName) || config.matchClosing === false) {
         setStyle = "tag";
         return closeState;
       } else {
@@ -268,7 +271,7 @@
       var tagName = state.tagName, tagStart = state.tagStart;
       state.tagName = state.tagStart = null;
       if (type == "selfcloseTag" ||
-          Kludges.autoSelfClosers.hasOwnProperty(tagName)) {
+          config.autoSelfClosers.hasOwnProperty(tagName)) {
         maybePopContext(state, tagName);
       } else {
         maybePopContext(state, tagName);
@@ -281,12 +284,12 @@
   }
   function attrEqState(type, stream, state) {
     if (type == "equals") return attrValueState;
-    if (!Kludges.allowMissing) setStyle = "error";
+    if (!config.allowMissing) setStyle = "error";
     return attrState(type, stream, state);
   }
   function attrValueState(type, stream, state) {
     if (type == "string") return attrContinuedState;
-    if (type == "word" && Kludges.allowUnquoted) {setStyle = "string"; return attrState;}
+    if (type == "word" && config.allowUnquoted) {setStyle = "string"; return attrState;}
     setStyle = "error";
     return attrState(type, stream, state);
   }
@@ -296,12 +299,14 @@
   }
 
   return {
-    startState: function() {
-      return {tokenize: inText,
-              state: baseState,
-              indented: 0,
-              tagName: null, tagStart: null,
-              context: null};
+    startState: function(baseIndent) {
+      var state = {tokenize: inText,
+                   state: baseState,
+                   indented: baseIndent || 0,
+                   tagName: null, tagStart: null,
+                   context: null}
+      if (baseIndent != null) state.baseIndent = baseIndent
+      return state
     },
 
     token: function(stream, state) {
@@ -334,19 +339,19 @@
         return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0;
       // Indent the starts of attribute names.
       if (state.tagName) {
-        if (multilineTagIndentPastTag)
+        if (config.multilineTagIndentPastTag !== false)
           return state.tagStart + state.tagName.length + 2;
         else
-          return state.tagStart + indentUnit * multilineTagIndentFactor;
+          return state.tagStart + indentUnit * (config.multilineTagIndentFactor || 1);
       }
-      if (alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0;
+      if (config.alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0;
       var tagAfter = textAfter && /^<(\/)?([\w_:\.-]*)/.exec(textAfter);
       if (tagAfter && tagAfter[1]) { // Closing tag spotted
         while (context) {
           if (context.tagName == tagAfter[2]) {
             context = context.prev;
             break;
-          } else if (Kludges.implicitlyClosed.hasOwnProperty(context.tagName)) {
+          } else if (config.implicitlyClosed.hasOwnProperty(context.tagName)) {
             context = context.prev;
           } else {
             break;
@@ -354,25 +359,30 @@
         }
       } else if (tagAfter) { // Opening tag spotted
         while (context) {
-          var grabbers = Kludges.contextGrabbers[context.tagName];
+          var grabbers = config.contextGrabbers[context.tagName];
           if (grabbers && grabbers.hasOwnProperty(tagAfter[2]))
             context = context.prev;
           else
             break;
         }
       }
-      while (context && !context.startOfLine)
+      while (context && context.prev && !context.startOfLine)
         context = context.prev;
       if (context) return context.indent + indentUnit;
-      else return 0;
+      else return state.baseIndent || 0;
     },
 
     electricInput: /<\/[\s\w:]+>$/,
     blockCommentStart: "<!--",
     blockCommentEnd: "-->",
 
-    configuration: parserConfig.htmlMode ? "html" : "xml",
-    helperType: parserConfig.htmlMode ? "html" : "xml"
+    configuration: config.htmlMode ? "html" : "xml",
+    helperType: config.htmlMode ? "html" : "xml",
+
+    skipAttribute: function(state) {
+      if (state.state == attrValueState)
+        state.state = attrState
+    }
   };
 });
 
@@ -381,4 +391,4 @@
 if (!CodeMirror.mimeModes.hasOwnProperty("text/html"))
   CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true});
 
-});
+});
\ No newline at end of file
diff --git a/third_party/WebKit/Source/devtools/front_end/cm_modes/jsx.js b/third_party/WebKit/Source/devtools/front_end/cm_modes/jsx.js
new file mode 100644
index 0000000..c3d227a
--- /dev/null
+++ b/third_party/WebKit/Source/devtools/front_end/cm_modes/jsx.js
@@ -0,0 +1,85 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"), require("../xml/xml"), require("../javascript/javascript"))
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror", "../xml/xml", "../javascript/javascript"], mod)
+  else // Plain browser env
+    mod(CodeMirror)
+})(function(CodeMirror) {
+  "use strict"
+
+  function copyContext(context) {
+    return {state: CodeMirror.copyState(context.mode, context.state),
+            mode: context.mode,
+            depth: context.depth,
+            prev: context.prev && copyContext(context.prev)}
+  }
+
+  CodeMirror.defineMode("jsx", function(config) {
+    var xmlMode = CodeMirror.getMode(config, "xml")
+    var jsMode = CodeMirror.getMode(config, "javascript")
+
+    return {
+      startState: function() {
+        return {context: {state: CodeMirror.startState(jsMode), mode: jsMode}}
+      },
+
+      copyState: function(state) {
+        return {context: copyContext(state.context)}
+      },
+
+      token: function(stream, state) {
+        var cx = state.context
+        if (cx.mode == xmlMode) {
+          if (stream.peek() == "{") {
+            xmlMode.skipAttribute(cx.state)
+            state.context = {state: CodeMirror.startState(jsMode, xmlMode.indent(cx.state, "")),
+                             mode: jsMode,
+                             depth: 1,
+                             prev: state.context}
+            return jsMode.token(stream, state.context.state)
+          } else { // FIXME skip attribute
+            var style = xmlMode.token(stream, cx.state), cur, brace
+            if (/\btag\b/.test(style) && !cx.state.context && /^\/?>$/.test(stream.current()))
+              state.context = state.context.prev
+            else if (!style && (brace = (cur = stream.current()).indexOf("{")) > -1)
+              stream.backUp(cur.length - brace)
+            return style
+          }
+        } else { // jsMode
+          if (stream.peek() == "<" && jsMode.expressionAllowed(stream, cx.state)) {
+            jsMode.skipExpression(cx.state)
+            state.context = {state: CodeMirror.startState(xmlMode, jsMode.indent(cx.state, "")),
+                             mode: xmlMode,
+                             prev: state.context}
+            return xmlMode.token(stream, state.context.state)
+          } else {
+            var style = jsMode.token(stream, cx.state)
+            if (!style && cx.depth != null) {
+              var cur = stream.current()
+              if (cur == "{") {
+                cx.depth++
+              } else if (cur == "}") {
+                if (--cx.depth == 0) state.context = state.context.prev
+              }
+            }
+            return style
+          }
+        }
+      },
+
+      indent: function(state, textAfter, fullLine) {
+        return state.context.mode.indent(state.context.state, textAfter, fullLine)
+      },
+
+      innerMode: function(state) {
+        return state.context[state.context.length - 1]
+      }
+    }
+  }, "xml", "javascript")
+
+  CodeMirror.defineMIME("text/jsx", "jsx")
+})
diff --git a/third_party/WebKit/Source/devtools/front_end/cm_modes/module.json b/third_party/WebKit/Source/devtools/front_end/cm_modes/module.json
index 4e8ae82..78cbd9b50 100644
--- a/third_party/WebKit/Source/devtools/front_end/cm_modes/module.json
+++ b/third_party/WebKit/Source/devtools/front_end/cm_modes/module.json
@@ -74,6 +74,14 @@
         {
             "type": "@WebInspector.CodeMirrorMimeMode",
             "className": "WebInspector.DefaultCodeMirrorMimeMode",
+            "fileName": "jsx.js",
+            "mimeTypes": [
+                "text/jsx"
+            ]
+        },
+        {
+            "type": "@WebInspector.CodeMirrorMimeMode",
+            "className": "WebInspector.DefaultCodeMirrorMimeMode",
             "fileName": "stylus.js",
             "mimeTypes": [
                 "text/x-styl"
@@ -94,6 +102,7 @@
         "shell.js",
         "livescript.js",
         "clojure.js",
-        "stylus.js"
+        "stylus.js",
+        "jsx.js"
     ]
 }
diff --git a/third_party/WebKit/Source/devtools/front_end/common/ResourceType.js b/third_party/WebKit/Source/devtools/front_end/common/ResourceType.js
index b27624e..4cdb4dd31 100644
--- a/third_party/WebKit/Source/devtools/front_end/common/ResourceType.js
+++ b/third_party/WebKit/Source/devtools/front_end/common/ResourceType.js
@@ -215,7 +215,6 @@
 WebInspector.ResourceType.mimeTypeByExtension = {
     // Web extensions
     "js": "text/javascript",
-    "jsx": "text/javascript",
     "css": "text/css",
     "html": "text/html",
     "htm": "text/html",
@@ -286,6 +285,9 @@
     // Stylus
     "styl": "text/x-styl",
 
+    // JSX
+    "jsx": "text/jsx",
+
     // Image
     "jpeg": "image/jpeg",
     "jpg": "image/jpeg",
diff --git a/third_party/WebKit/Source/devtools/front_end/components/ObjectPropertiesSection.js b/third_party/WebKit/Source/devtools/front_end/components/ObjectPropertiesSection.js
index 9592a28..da2f5e77 100644
--- a/third_party/WebKit/Source/devtools/front_end/components/ObjectPropertiesSection.js
+++ b/third_party/WebKit/Source/devtools/front_end/components/ObjectPropertiesSection.js
@@ -630,7 +630,7 @@
                     property.parentObject = null;
                     this.appendChild(new WebInspector.ObjectPropertyTreeElement(property));
                 } else {
-                    var scopeRef = new WebInspector.ScopeRef(i, undefined, this._remoteObject.objectId);
+                    var scopeRef = new WebInspector.ScopeRef(i, undefined);
                     var remoteObject = runtimeModel.createScopeRemoteObject(scope.object, scopeRef);
                     var scopeTreeElement = new WebInspector.ScopeTreeElement(title, remoteObject);
                     this.appendChild(scopeTreeElement);
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/CSSMetadata.js b/third_party/WebKit/Source/devtools/front_end/sdk/CSSMetadata.js
index 7c19cf7..5070d7a2 100644
--- a/third_party/WebKit/Source/devtools/front_end/sdk/CSSMetadata.js
+++ b/third_party/WebKit/Source/devtools/front_end/sdk/CSSMetadata.js
@@ -227,7 +227,7 @@
         "horizontal-tb", "vertical-rl", "vertical-lr"
     ] },
     "-webkit-writing-mode": { values: [
-        "lr", "rl", "tb", "lr-tb", "rl-tb", "tb-rl", "horizontal-tb", "vertical-rl", "vertical-lr", "horizontal-bt"
+        "lr", "rl", "tb", "lr-tb", "rl-tb", "tb-rl", "horizontal-tb", "vertical-rl", "vertical-lr"
     ] },
     "border-collapse": { values: [
         "collapse", "separate"
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 98b2d784..6250aa1 100644
--- a/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerModel.js
+++ b/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerModel.js
@@ -808,12 +808,11 @@
      * @param {string} variableName
      * @param {!RuntimeAgent.CallArgument} newValue
      * @param {string} callFrameId
-     * @param {string} functionObjectId
      * @param {function(string=)=} callback
      */
-    setVariableValue: function(scopeNumber, variableName, newValue, callFrameId, functionObjectId, callback)
+    setVariableValue: function(scopeNumber, variableName, newValue, callFrameId, callback)
     {
-        this._agent.setVariableValue(scopeNumber, variableName, newValue, callFrameId, functionObjectId, innerCallback);
+        this._agent.setVariableValue(scopeNumber, variableName, newValue, callFrameId, innerCallback);
 
         /**
          * @param {?Protocol.Error} error
@@ -1376,7 +1375,7 @@
 
         var declarativeScope = this._type !== DebuggerAgent.ScopeType.With && this._type !== DebuggerAgent.ScopeType.Global;
         if (declarativeScope)
-            this._object = runtimeModel.createScopeRemoteObject(this._payload.object, new WebInspector.ScopeRef(this._ordinal, this._callFrame.id, undefined));
+            this._object = runtimeModel.createScopeRemoteObject(this._payload.object, new WebInspector.ScopeRef(this._ordinal, this._callFrame.id));
         else
             this._object = runtimeModel.createRemoteObject(this._payload.object);
 
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/RemoteObject.js b/third_party/WebKit/Source/devtools/front_end/sdk/RemoteObject.js
index 7ef3049..8f2c0d9 100644
--- a/third_party/WebKit/Source/devtools/front_end/sdk/RemoteObject.js
+++ b/third_party/WebKit/Source/devtools/front_end/sdk/RemoteObject.js
@@ -1048,8 +1048,13 @@
          */
         function wrappedCallback(properties, internalProperties)
         {
-            if (this._scopeRef && Array.isArray(properties))
+            if (this._scopeRef && Array.isArray(properties)) {
                 this._savedScopeProperties = properties.slice();
+                if (!this._scopeRef.callFrameId) {
+                    for (var property of this._savedScopeProperties)
+                        property.writable = false;
+                }
+            }
             callback(properties, internalProperties);
         }
 
@@ -1068,7 +1073,7 @@
     doSetObjectPropertyValue: function(result, argumentName, callback)
     {
         var name = /** @type {string} */ (argumentName.value);
-        this._debuggerModel.setVariableValue(this._scopeRef.number, name, WebInspector.RemoteObject.toCallArgument(result), this._scopeRef.callFrameId, this._scopeRef.functionId, setVariableValueCallback.bind(this));
+        this._debuggerModel.setVariableValue(this._scopeRef.number, name, WebInspector.RemoteObject.toCallArgument(result), this._scopeRef.callFrameId, setVariableValueCallback.bind(this));
 
         /**
          * @param {string=} error
@@ -1094,17 +1099,14 @@
 };
 
 /**
- * Either callFrameId or functionId (exactly one) must be defined.
  * @constructor
  * @param {number} number
  * @param {string=} callFrameId
- * @param {string=} functionId
  */
-WebInspector.ScopeRef = function(number, callFrameId, functionId)
+WebInspector.ScopeRef = function(number, callFrameId)
 {
     this.number = number;
     this.callFrameId = callFrameId;
-    this.functionId = functionId;
 }
 
 /**
diff --git a/third_party/WebKit/Source/devtools/protocol.json b/third_party/WebKit/Source/devtools/protocol.json
index 0643d498..beaab1e1 100644
--- a/third_party/WebKit/Source/devtools/protocol.json
+++ b/third_party/WebKit/Source/devtools/protocol.json
@@ -3703,11 +3703,10 @@
                     { "name": "scopeNumber", "type": "integer", "description": "0-based number of scope as was listed in scope chain. Only 'local', 'closure' and 'catch' scope types are allowed. Other scopes could be manipulated manually." },
                     { "name": "variableName", "type": "string", "description": "Variable name." },
                     { "name": "newValue", "$ref": "Runtime.CallArgument", "description": "New variable value." },
-                    { "name": "callFrameId", "$ref": "CallFrameId", "optional": true, "description": "Id of callframe that holds variable." },
-                    { "name": "functionObjectId", "$ref": "Runtime.RemoteObjectId", "optional": true, "description": "Object id of closure (function) that holds variable." }
+                    { "name": "callFrameId", "$ref": "CallFrameId", "description": "Id of callframe that holds variable." }
                 ],
                 "hidden": true,
-                "description": "Changes value of variable in a callframe or a closure. Either callframe or function must be specified. Object-based scopes are not supported and must be mutated manually."
+                "description": "Changes value of variable in a callframe. Object-based scopes are not supported and must be mutated manually."
             },
             {
                 "name": "getBacktrace",
diff --git a/third_party/WebKit/Source/modules/webgl/DEPS b/third_party/WebKit/Source/modules/webgl/DEPS
new file mode 100644
index 0000000..8109dc0a
--- /dev/null
+++ b/third_party/WebKit/Source/modules/webgl/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+    "+gpu/command_buffer/client/gles2_interface.h",
+]
diff --git a/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContext.cpp b/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContext.cpp
index 05bc1bd7..888b74d 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContext.cpp
+++ b/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContext.cpp
@@ -40,7 +40,7 @@
     OwnPtr<WebGraphicsContext3D> context(createWebGraphicsContext3D(canvas, attributes, 2));
     if (!context)
         return nullptr;
-    OwnPtr<Extensions3DUtil> extensionsUtil = Extensions3DUtil::create(context.get());
+    OwnPtr<Extensions3DUtil> extensionsUtil = Extensions3DUtil::create(context.get(), context->getGLES2Interface());
     if (!extensionsUtil)
         return nullptr;
     if (extensionsUtil->supportsExtension("GL_EXT_debug_marker")) {
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContext.cpp b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContext.cpp
index 56e28c6..52b6984 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContext.cpp
+++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContext.cpp
@@ -70,7 +70,7 @@
     OwnPtr<WebGraphicsContext3D> context(createWebGraphicsContext3D(canvas, attributes, 1));
     if (!context)
         return nullptr;
-    OwnPtr<Extensions3DUtil> extensionsUtil = Extensions3DUtil::create(context.get());
+    OwnPtr<Extensions3DUtil> extensionsUtil = Extensions3DUtil::create(context.get(), context->getGLES2Interface());
     if (!extensionsUtil)
         return nullptr;
     if (extensionsUtil->supportsExtension("GL_EXT_debug_marker")) {
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
index daa0ac8..48a944b 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
+++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
@@ -45,6 +45,7 @@
 #include "core/layout/LayoutBox.h"
 #include "core/loader/FrameLoader.h"
 #include "core/loader/FrameLoaderClient.h"
+#include "gpu/command_buffer/client/gles2_interface.h"
 #include "modules/webgl/ANGLEInstancedArrays.h"
 #include "modules/webgl/CHROMIUMSubscribeUniform.h"
 #include "modules/webgl/CHROMIUMValuebuffer.h"
@@ -5072,9 +5073,11 @@
 Extensions3DUtil* WebGLRenderingContextBase::extensionsUtil()
 {
     if (!m_extensionsUtil) {
-        m_extensionsUtil = Extensions3DUtil::create(webContext());
+        WebGraphicsContext3D* context = webContext();
+        gpu::gles2::GLES2Interface* gl = context->getGLES2Interface();
+        m_extensionsUtil = Extensions3DUtil::create(context, gl);
         // The only reason the ExtensionsUtil should be invalid is if the webContext is lost.
-        ASSERT(m_extensionsUtil->isValid() || webContext()->isContextLost());
+        ASSERT(m_extensionsUtil->isValid() || gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR);
     }
     return m_extensionsUtil.get();
 }
diff --git a/third_party/WebKit/Source/platform/BUILD.gn b/third_party/WebKit/Source/platform/BUILD.gn
index 3254fb5..ba99374 100644
--- a/third_party/WebKit/Source/platform/BUILD.gn
+++ b/third_party/WebKit/Source/platform/BUILD.gn
@@ -324,6 +324,7 @@
     "//base",
     "//cc",
     "//gpu/command_buffer/client:gles2_c_lib",
+    "//gpu/command_buffer/client:gles2_interface",
     "//skia",
     "//third_party:jpeg",
     "//third_party/WebKit/Source/wtf",
diff --git a/third_party/WebKit/Source/platform/animation/CompositorAnimationPlayer.cpp b/third_party/WebKit/Source/platform/animation/CompositorAnimationPlayer.cpp
index 9122829..819727c 100644
--- a/third_party/WebKit/Source/platform/animation/CompositorAnimationPlayer.cpp
+++ b/third_party/WebKit/Source/platform/animation/CompositorAnimationPlayer.cpp
@@ -5,6 +5,7 @@
 #include "platform/animation/CompositorAnimationPlayer.h"
 
 #include "cc/animation/animation_id_provider.h"
+#include "cc/animation/animation_timeline.h"
 #include "platform/animation/CompositorAnimation.h"
 #include "platform/animation/CompositorAnimationDelegate.h"
 #include "public/platform/WebLayer.h"
@@ -19,6 +20,11 @@
 
 CompositorAnimationPlayer::~CompositorAnimationPlayer()
 {
+    setAnimationDelegate(nullptr);
+    // Detach player from timeline, otherwise it stays there (leaks) until
+    // compositor shutdown.
+    if (m_animationPlayer->animation_timeline())
+        m_animationPlayer->animation_timeline()->DetachPlayer(m_animationPlayer);
 }
 
 cc::AnimationPlayer* CompositorAnimationPlayer::animationPlayer() const
diff --git a/third_party/WebKit/Source/platform/blink_platform.gyp b/third_party/WebKit/Source/platform/blink_platform.gyp
index 9f7ac0e..86289b0 100644
--- a/third_party/WebKit/Source/platform/blink_platform.gyp
+++ b/third_party/WebKit/Source/platform/blink_platform.gyp
@@ -133,6 +133,7 @@
       '<(DEPTH)/cc/cc.gyp:cc',
       '<(DEPTH)/device/battery/battery.gyp:device_battery_mojo_bindings',
       '<(DEPTH)/gpu/gpu.gyp:gles2_c_lib',
+      '<(DEPTH)/gpu/gpu.gyp:gles2_implementation',
       '<(DEPTH)/mojo/mojo_edk.gyp:mojo_system_impl',
       '<(DEPTH)/mojo/mojo_public.gyp:mojo_cpp_bindings',
       '<(DEPTH)/skia/skia.gyp:skia',
diff --git a/third_party/WebKit/Source/platform/blink_platform.gypi b/third_party/WebKit/Source/platform/blink_platform.gypi
index 4bcb240..6734a3c 100644
--- a/third_party/WebKit/Source/platform/blink_platform.gypi
+++ b/third_party/WebKit/Source/platform/blink_platform.gypi
@@ -1230,6 +1230,7 @@
       'graphics/ImageDecodingStoreTest.cpp',
       'graphics/ImageFrameGeneratorTest.cpp',
       'graphics/ImageLayerChromiumTest.cpp',
+      'graphics/test/MockGLES2Interface.h',
       'graphics/test/MockImageDecoder.h',
       'graphics/test/MockWebGraphicsContext3D.h',
       'threading/BackgroundTaskRunnerTest.cpp',
diff --git a/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp b/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp
index 90ef507..5e7d0d3 100644
--- a/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp
+++ b/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp
@@ -25,6 +25,7 @@
 
 #include "platform/graphics/Canvas2DLayerBridge.h"
 
+#include "gpu/command_buffer/client/gles2_interface.h"
 #include "platform/Histogram.h"
 #include "platform/RuntimeEnabledFeatures.h"
 #include "platform/TraceEvent.h"
@@ -178,7 +179,7 @@
     else
         accelerate = hint == PreferAcceleration || hint == PreferAccelerationAfterVisibilityChange;
 
-    if (accelerate && (!m_contextProvider || m_contextProvider->context3d()->isContextLost()))
+    if (accelerate && (!m_contextProvider || m_contextProvider->contextGL()->GetGraphicsResetStatusKHR() != GL_NO_ERROR))
         accelerate = false;
     return accelerate;
 }
@@ -727,7 +728,7 @@
         return true;
     if (!m_surface)
         return false;
-    if (m_contextProvider->context3d()->isContextLost()) {
+    if (m_contextProvider->contextGL()->GetGraphicsResetStatusKHR() != GL_NO_ERROR) {
         m_surface.clear();
         for (auto mailboxInfo = m_mailboxes.begin(); mailboxInfo != m_mailboxes.end(); ++mailboxInfo) {
             if (mailboxInfo->m_image)
@@ -747,13 +748,13 @@
         return false;
     ASSERT(isAccelerated() && !m_surface);
 
-    WebGraphicsContext3D* sharedContext = 0;
+    gpu::gles2::GLES2Interface* sharedGL = nullptr;
     m_layer->clearTexture();
     m_contextProvider = adoptPtr(Platform::current()->createSharedOffscreenGraphicsContext3DProvider());
     if (m_contextProvider)
-        sharedContext = m_contextProvider->context3d();
+        sharedGL = m_contextProvider->contextGL();
 
-    if (sharedContext && !sharedContext->isContextLost()) {
+    if (sharedGL && sharedGL->GetGraphicsResetStatusKHR() == GL_NO_ERROR) {
         GrContext* grCtx = m_contextProvider->grContext();
         bool surfaceIsAccelerated;
         RefPtr<SkSurface> surface(createSkSurface(grCtx, m_size, m_msaaSampleCount, m_opacityMode, &surfaceIsAccelerated));
@@ -819,7 +820,7 @@
 void Canvas2DLayerBridge::mailboxReleased(const WebExternalTextureMailbox& mailbox, bool lostResource)
 {
     ASSERT(isAccelerated() || isHibernating());
-    bool contextLost = !isHibernating() && (!m_surface || m_contextProvider->context3d()->isContextLost());
+    bool contextLost = !isHibernating() && (!m_surface || m_contextProvider->contextGL()->GetGraphicsResetStatusKHR() != GL_NO_ERROR);
     ASSERT(m_mailboxes.last().m_parentLayerBridge.get() == this);
 
     // Mailboxes are typically released in FIFO order, so we iterate
diff --git a/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridgeTest.cpp b/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridgeTest.cpp
index 89f071d0..2508eaf 100644
--- a/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridgeTest.cpp
+++ b/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridgeTest.cpp
@@ -26,11 +26,13 @@
 
 #include "SkSurface.h"
 #include "base/memory/scoped_ptr.h"
+#include "gpu/command_buffer/client/gles2_interface.h"
 #include "platform/Task.h"
 #include "platform/ThreadSafeFunctional.h"
 #include "platform/WaitableEvent.h"
 #include "platform/graphics/ImageBuffer.h"
 #include "platform/graphics/UnacceleratedImageBufferSurface.h"
+#include "platform/graphics/test/MockGLES2Interface.h"
 #include "platform/graphics/test/MockWebGraphicsContext3D.h"
 #include "public/platform/Platform.h"
 #include "public/platform/WebExternalBitmap.h"
@@ -68,8 +70,9 @@
 
 class MockWebGraphicsContext3DProvider : public WebGraphicsContext3DProvider {
 public:
-    MockWebGraphicsContext3DProvider(WebGraphicsContext3D* context3d)
+    MockWebGraphicsContext3DProvider(WebGraphicsContext3D* context3d, gpu::gles2::GLES2Interface* gl)
         : m_context3d(context3d)
+        , m_gl(gl)
     {
         scoped_ptr<SkGLContext> glContext(SkNullGLContext::Create());
         glContext->makeCurrent();
@@ -86,8 +89,14 @@
         return m_grContext.get();
     }
 
+    gpu::gles2::GLES2Interface* contextGL() override
+    {
+        return m_gl;
+    }
+
 private:
     WebGraphicsContext3D* m_context3d;
+    gpu::gles2::GLES2Interface* m_gl;
     RefPtr<GrContext> m_grContext;
 };
 
@@ -153,7 +162,8 @@
     void fullLifecycleTest()
     {
         MockCanvasContext mainMock;
-        OwnPtr<MockWebGraphicsContext3DProvider> mainMockProvider = adoptPtr(new MockWebGraphicsContext3DProvider(&mainMock));
+        MockGLES2Interface mockGL;
+        OwnPtr<MockWebGraphicsContext3DProvider> mainMockProvider = adoptPtr(new MockWebGraphicsContext3DProvider(&mainMock, &mockGL));
 
         ::testing::Mock::VerifyAndClearExpectations(&mainMock);
 
@@ -174,12 +184,13 @@
     void fallbackToSoftwareIfContextLost()
     {
         MockCanvasContext mainMock;
-        OwnPtr<MockWebGraphicsContext3DProvider> mainMockProvider = adoptPtr(new MockWebGraphicsContext3DProvider(&mainMock));
+        MockGLES2Interface mockGL;
+        OwnPtr<MockWebGraphicsContext3DProvider> mainMockProvider = adoptPtr(new MockWebGraphicsContext3DProvider(&mainMock, &mockGL));
 
         ::testing::Mock::VerifyAndClearExpectations(&mainMock);
 
         {
-            mainMock.fakeContextLost();
+            mockGL.setIsContextLost(true);
             Canvas2DLayerBridgePtr bridge(adoptRef(new Canvas2DLayerBridge(mainMockProvider.release(), IntSize(300, 150), 0, NonOpaque, Canvas2DLayerBridge::EnableAcceleration)));
             ::testing::Mock::VerifyAndClearExpectations(&mainMock);
             EXPECT_TRUE(bridge->checkSurfaceValid());
@@ -198,7 +209,8 @@
 
         {
             // No fallback case
-            OwnPtr<MockWebGraphicsContext3DProvider> mainMockProvider = adoptPtr(new MockWebGraphicsContext3DProvider(&mainMock));
+            MockGLES2Interface mockGL;
+            OwnPtr<MockWebGraphicsContext3DProvider> mainMockProvider = adoptPtr(new MockWebGraphicsContext3DProvider(&mainMock, &mockGL));
             Canvas2DLayerBridgePtr bridge(adoptRef(new Canvas2DLayerBridge(mainMockProvider.release(), IntSize(300, 150), 0, NonOpaque, Canvas2DLayerBridge::EnableAcceleration)));
             ::testing::Mock::VerifyAndClearExpectations(&mainMock);
             EXPECT_TRUE(bridge->checkSurfaceValid());
@@ -211,7 +223,8 @@
 
         {
             // Fallback case
-            OwnPtr<MockWebGraphicsContext3DProvider> mainMockProvider = adoptPtr(new MockWebGraphicsContext3DProvider(&mainMock));
+            MockGLES2Interface mockGL;
+            OwnPtr<MockWebGraphicsContext3DProvider> mainMockProvider = adoptPtr(new MockWebGraphicsContext3DProvider(&mainMock, &mockGL));
             GrContext* gr = mainMockProvider->grContext();
             Canvas2DLayerBridgePtr bridge(adoptRef(new Canvas2DLayerBridge(mainMockProvider.release(), IntSize(300, 150), 0, NonOpaque, Canvas2DLayerBridge::EnableAcceleration)));
             ::testing::Mock::VerifyAndClearExpectations(&mainMock);
@@ -230,7 +243,8 @@
     void noDrawOnContextLostTest()
     {
         MockCanvasContext mainMock;
-        OwnPtr<MockWebGraphicsContext3DProvider> mainMockProvider = adoptPtr(new MockWebGraphicsContext3DProvider(&mainMock));
+        MockGLES2Interface mockGL;
+        OwnPtr<MockWebGraphicsContext3DProvider> mainMockProvider = adoptPtr(new MockWebGraphicsContext3DProvider(&mainMock, &mockGL));
 
         ::testing::Mock::VerifyAndClearExpectations(&mainMock);
 
@@ -242,7 +256,7 @@
             uint32_t genID = bridge->getOrCreateSurface()->generationID();
             bridge->canvas()->drawRect(SkRect::MakeXYWH(0, 0, 1, 1), paint);
             EXPECT_EQ(genID, bridge->getOrCreateSurface()->generationID());
-            mainMock.fakeContextLost();
+            mockGL.setIsContextLost(true);
             EXPECT_EQ(genID, bridge->getOrCreateSurface()->generationID());
             bridge->canvas()->drawRect(SkRect::MakeXYWH(0, 0, 1, 1), paint);
             EXPECT_EQ(genID, bridge->getOrCreateSurface()->generationID());
@@ -260,7 +274,8 @@
     void prepareMailboxWithBitmapTest()
     {
         MockCanvasContext mainMock;
-        OwnPtr<MockWebGraphicsContext3DProvider> mainMockProvider = adoptPtr(new MockWebGraphicsContext3DProvider(&mainMock));
+        MockGLES2Interface mockGL;
+        OwnPtr<MockWebGraphicsContext3DProvider> mainMockProvider = adoptPtr(new MockWebGraphicsContext3DProvider(&mainMock, &mockGL));
         Canvas2DLayerBridgePtr bridge(adoptRef(new Canvas2DLayerBridge(mainMockProvider.release(), IntSize(300, 150), 0, NonOpaque, Canvas2DLayerBridge::ForceAccelerationForTesting)));
         bridge->m_lastImageId = 1;
 
@@ -272,13 +287,14 @@
     void prepareMailboxAndLoseResourceTest()
     {
         MockCanvasContext mainMock;
+        MockGLES2Interface mockGL;
         bool lostResource = true;
 
         // Prepare a mailbox, then report the resource as lost.
         // This test passes by not crashing and not triggering assertions.
         {
             WebExternalTextureMailbox mailbox;
-            OwnPtr<MockWebGraphicsContext3DProvider> mainMockProvider = adoptPtr(new MockWebGraphicsContext3DProvider(&mainMock));
+            OwnPtr<MockWebGraphicsContext3DProvider> mainMockProvider = adoptPtr(new MockWebGraphicsContext3DProvider(&mainMock, &mockGL));
             Canvas2DLayerBridgePtr bridge(adoptRef(new Canvas2DLayerBridge(mainMockProvider.release(), IntSize(300, 150), 0, NonOpaque, Canvas2DLayerBridge::ForceAccelerationForTesting)));
             bridge->prepareMailbox(&mailbox, 0);
             bridge->mailboxReleased(mailbox, lostResource);
@@ -286,7 +302,7 @@
 
         // Retry with mailbox released while bridge destruction is in progress
         {
-            OwnPtr<MockWebGraphicsContext3DProvider> mainMockProvider = adoptPtr(new MockWebGraphicsContext3DProvider(&mainMock));
+            OwnPtr<MockWebGraphicsContext3DProvider> mainMockProvider = adoptPtr(new MockWebGraphicsContext3DProvider(&mainMock, &mockGL));
             WebExternalTextureMailbox mailbox;
             Canvas2DLayerBridge* rawBridge;
             {
@@ -303,9 +319,10 @@
     void accelerationHintTest()
     {
         MockCanvasContext mainMock;
+        MockGLES2Interface mockGL;
         {
 
-            OwnPtr<MockWebGraphicsContext3DProvider> mainMockProvider = adoptPtr(new MockWebGraphicsContext3DProvider(&mainMock));
+            OwnPtr<MockWebGraphicsContext3DProvider> mainMockProvider = adoptPtr(new MockWebGraphicsContext3DProvider(&mainMock, &mockGL));
             ::testing::Mock::VerifyAndClearExpectations(&mainMock);
             Canvas2DLayerBridgePtr bridge(adoptRef(new Canvas2DLayerBridge(mainMockProvider.release(), IntSize(300, 300), 0, NonOpaque, Canvas2DLayerBridge::EnableAcceleration)));
             ::testing::Mock::VerifyAndClearExpectations(&mainMock);
@@ -319,7 +336,7 @@
         ::testing::Mock::VerifyAndClearExpectations(&mainMock);
 
         {
-            OwnPtr<MockWebGraphicsContext3DProvider> mainMockProvider = adoptPtr(new MockWebGraphicsContext3DProvider(&mainMock));
+            OwnPtr<MockWebGraphicsContext3DProvider> mainMockProvider = adoptPtr(new MockWebGraphicsContext3DProvider(&mainMock, &mockGL));
             ::testing::Mock::VerifyAndClearExpectations(&mainMock);
             Canvas2DLayerBridgePtr bridge(adoptRef(new Canvas2DLayerBridge(mainMockProvider.release(), IntSize(300, 300), 0, NonOpaque, Canvas2DLayerBridge::EnableAcceleration)));
             ::testing::Mock::VerifyAndClearExpectations(&mainMock);
@@ -376,10 +393,9 @@
     virtual ~MockLogger() { }
 };
 
-
-void runCreateBridgeTask(Canvas2DLayerBridgePtr* bridgePtr, MockCanvasContext* mockCanvasContext, Canvas2DLayerBridgeTest* testHost, WaitableEvent* doneEvent)
+void runCreateBridgeTask(Canvas2DLayerBridgePtr* bridgePtr, MockCanvasContext* mockCanvasContext, gpu::gles2::GLES2Interface* gl, Canvas2DLayerBridgeTest* testHost, WaitableEvent* doneEvent)
 {
-    OwnPtr<MockWebGraphicsContext3DProvider> mainMockProvider = adoptPtr(new MockWebGraphicsContext3DProvider(mockCanvasContext));
+    OwnPtr<MockWebGraphicsContext3DProvider> mainMockProvider = adoptPtr(new MockWebGraphicsContext3DProvider(mockCanvasContext, gl));
     *bridgePtr = testHost->makeBridge(mainMockProvider.release(), IntSize(300, 300), Canvas2DLayerBridge::EnableAcceleration);
     // draw+flush to trigger the creation of a GPU surface
     (*bridgePtr)->didDraw(FloatRect(0, 0, 1, 1));
@@ -388,7 +404,7 @@
     doneEvent->signal();
 }
 
-void postAndWaitCreateBridgeTask(const WebTraceLocation& location, WebThread* testThread, Canvas2DLayerBridgePtr* bridgePtr, MockCanvasContext* mockCanvasContext, Canvas2DLayerBridgeTest* testHost)
+void postAndWaitCreateBridgeTask(const WebTraceLocation& location, WebThread* testThread, Canvas2DLayerBridgePtr* bridgePtr, MockCanvasContext* mockCanvasContext, gpu::gles2::GLES2Interface* gl, Canvas2DLayerBridgeTest* testHost)
 {
     OwnPtr<WaitableEvent> bridgeCreatedEvent = adoptPtr(new WaitableEvent());
     testThread->getWebTaskRunner()->postTask(
@@ -396,6 +412,7 @@
         threadSafeBind(&runCreateBridgeTask,
             AllowCrossThreadAccess(bridgePtr),
             AllowCrossThreadAccess(mockCanvasContext),
+            AllowCrossThreadAccess(gl),
             AllowCrossThreadAccess(testHost),
             AllowCrossThreadAccess(bridgeCreatedEvent.get())));
     bridgeCreatedEvent->wait();
@@ -469,12 +486,13 @@
 #endif
 {
     MockCanvasContext mainMock;
+    MockGLES2Interface mockGL;
     OwnPtr<WebThread> testThread = adoptPtr(Platform::current()->createThread("TestThread"));
 
     // The Canvas2DLayerBridge has to be created on the thread that will use it
     // to avoid WeakPtr thread check issues.
     Canvas2DLayerBridgePtr bridge;
-    postAndWaitCreateBridgeTask(BLINK_FROM_HERE, testThread.get(), &bridge, &mainMock, this);
+    postAndWaitCreateBridgeTask(BLINK_FROM_HERE, testThread.get(), &bridge, &mainMock, &mockGL, this);
 
     // Register an alternate Logger for tracking hibernation events
     OwnPtr<MockLogger> mockLogger = adoptPtr(new MockLogger);
@@ -515,12 +533,13 @@
 #endif
 {
     MockCanvasContext mainMock;
+    MockGLES2Interface mockGL;
     OwnPtr<WebThread> testThread = adoptPtr(Platform::current()->createThread("TestThread"));
 
     // The Canvas2DLayerBridge has to be created on the thread that will use it
     // to avoid WeakPtr thread check issues.
     Canvas2DLayerBridgePtr bridge;
-    postAndWaitCreateBridgeTask(BLINK_FROM_HERE, testThread.get(), &bridge, &mainMock, this);
+    postAndWaitCreateBridgeTask(BLINK_FROM_HERE, testThread.get(), &bridge, &mainMock, &mockGL, this);
 
     // Register an alternate Logger for tracking hibernation events
     OwnPtr<MockLogger> mockLogger = adoptPtr(new MockLogger);
@@ -567,12 +586,13 @@
 #endif
 {
     MockCanvasContext mainMock;
+    MockGLES2Interface mockGL;
     OwnPtr<WebThread> testThread = adoptPtr(Platform::current()->createThread("TestThread"));
 
     // The Canvas2DLayerBridge has to be created on the thread that will use it
     // to avoid WeakPtr thread check issues.
     Canvas2DLayerBridgePtr bridge;
-    postAndWaitCreateBridgeTask(BLINK_FROM_HERE, testThread.get(), &bridge, &mainMock, this);
+    postAndWaitCreateBridgeTask(BLINK_FROM_HERE, testThread.get(), &bridge, &mainMock, &mockGL, this);
     bridge->disableDeferral(DisableDeferralReasonUnknown);
     MockImageBuffer mockImageBuffer;
     EXPECT_CALL(mockImageBuffer, resetCanvas(_)).Times(AnyNumber());
@@ -639,12 +659,13 @@
 #endif
 {
     MockCanvasContext mainMock;
+    MockGLES2Interface mockGL;
     OwnPtr<WebThread> testThread = adoptPtr(Platform::current()->createThread("TestThread"));
 
     // The Canvas2DLayerBridge has to be created on the thread that will use it
     // to avoid WeakPtr thread check issues.
     Canvas2DLayerBridgePtr bridge;
-    postAndWaitCreateBridgeTask(BLINK_FROM_HERE, testThread.get(), &bridge, &mainMock, this);
+    postAndWaitCreateBridgeTask(BLINK_FROM_HERE, testThread.get(), &bridge, &mainMock, &mockGL, this);
 
     // Register an alternate Logger for tracking hibernation events
     OwnPtr<MockLogger> mockLogger = adoptPtr(new MockLogger);
@@ -692,12 +713,13 @@
 #endif
 {
     MockCanvasContext mainMock;
+    MockGLES2Interface mockGL;
     OwnPtr<WebThread> testThread = adoptPtr(Platform::current()->createThread("TestThread"));
 
     // The Canvas2DLayerBridge has to be created on the thread that will use it
     // to avoid WeakPtr thread check issues.
     Canvas2DLayerBridgePtr bridge;
-    postAndWaitCreateBridgeTask(BLINK_FROM_HERE, testThread.get(), &bridge, &mainMock, this);
+    postAndWaitCreateBridgeTask(BLINK_FROM_HERE, testThread.get(), &bridge, &mainMock, &mockGL, this);
     MockImageBuffer mockImageBuffer;
     EXPECT_CALL(mockImageBuffer, resetCanvas(_)).Times(AnyNumber());
     bridge->setImageBuffer(&mockImageBuffer);
@@ -753,12 +775,13 @@
 #endif
 {
     MockCanvasContext mainMock;
+    MockGLES2Interface mockGL;
     OwnPtr<WebThread> testThread = adoptPtr(Platform::current()->createThread("TestThread"));
 
     // The Canvas2DLayerBridge has to be created on the thread that will use it
     // to avoid WeakPtr thread check issues.
     Canvas2DLayerBridgePtr bridge;
-    postAndWaitCreateBridgeTask(BLINK_FROM_HERE, testThread.get(), &bridge, &mainMock, this);
+    postAndWaitCreateBridgeTask(BLINK_FROM_HERE, testThread.get(), &bridge, &mainMock, &mockGL, this);
     MockImageBuffer mockImageBuffer;
     EXPECT_CALL(mockImageBuffer, resetCanvas(_)).Times(AnyNumber());
     bridge->setImageBuffer(&mockImageBuffer);
@@ -813,12 +836,13 @@
 #endif
 {
     MockCanvasContext mainMock;
+    MockGLES2Interface mockGL;
     OwnPtr<WebThread> testThread = adoptPtr(Platform::current()->createThread("TestThread"));
 
     // The Canvas2DLayerBridge has to be created on the thread that will use it
     // to avoid WeakPtr thread check issues.
     Canvas2DLayerBridgePtr bridge;
-    postAndWaitCreateBridgeTask(BLINK_FROM_HERE, testThread.get(), &bridge, &mainMock, this);
+    postAndWaitCreateBridgeTask(BLINK_FROM_HERE, testThread.get(), &bridge, &mainMock, &mockGL, this);
 
     // Register an alternate Logger for tracking hibernation events
     OwnPtr<MockLogger> mockLogger = adoptPtr(new MockLogger);
@@ -868,12 +892,13 @@
 #endif
 {
     MockCanvasContext mainMock;
+    MockGLES2Interface mockGL;
     OwnPtr<WebThread> testThread = adoptPtr(Platform::current()->createThread("TestThread"));
 
     // The Canvas2DLayerBridge has to be created on the thread that will use it
     // to avoid WeakPtr thread check issues.
     Canvas2DLayerBridgePtr bridge;
-    postAndWaitCreateBridgeTask(BLINK_FROM_HERE, testThread.get(), &bridge, &mainMock, this);
+    postAndWaitCreateBridgeTask(BLINK_FROM_HERE, testThread.get(), &bridge, &mainMock, &mockGL, this);
 
     // Register an alternate Logger for tracking hibernation events
     OwnPtr<MockLogger> mockLogger = adoptPtr(new MockLogger);
@@ -910,12 +935,13 @@
 #endif
 {
     MockCanvasContext mainMock;
+    MockGLES2Interface mockGL;
     OwnPtr<WebThread> testThread = adoptPtr(Platform::current()->createThread("TestThread"));
 
     // The Canvas2DLayerBridge has to be created on the thread that will use it
     // to avoid WeakPtr thread check issues.
     Canvas2DLayerBridgePtr bridge;
-    postAndWaitCreateBridgeTask(BLINK_FROM_HERE, testThread.get(), &bridge, &mainMock, this);
+    postAndWaitCreateBridgeTask(BLINK_FROM_HERE, testThread.get(), &bridge, &mainMock, &mockGL, this);
 
     // Register an alternate Logger for tracking hibernation events
     OwnPtr<MockLogger> mockLogger = adoptPtr(new MockLogger);
@@ -946,12 +972,13 @@
 #endif
 {
     MockCanvasContext mainMock;
+    MockGLES2Interface mockGL;
     OwnPtr<WebThread> testThread = adoptPtr(Platform::current()->createThread("TestThread"));
 
     // The Canvas2DLayerBridge has to be created on the thread that will use it
     // to avoid WeakPtr thread check issues.
     Canvas2DLayerBridgePtr bridge;
-    postAndWaitCreateBridgeTask(BLINK_FROM_HERE, testThread.get(), &bridge, &mainMock, this);
+    postAndWaitCreateBridgeTask(BLINK_FROM_HERE, testThread.get(), &bridge, &mainMock, &mockGL, this);
 
     // Register an alternate Logger for tracking hibernation events
     OwnPtr<MockLogger> mockLogger = adoptPtr(new MockLogger);
@@ -985,19 +1012,20 @@
 #endif
 {
     MockCanvasContext mainMock;
+    MockGLES2Interface mockGL;
     OwnPtr<WebThread> testThread = adoptPtr(Platform::current()->createThread("TestThread"));
 
     // The Canvas2DLayerBridge has to be created on the thread that will use it
     // to avoid WeakPtr thread check issues.
     Canvas2DLayerBridgePtr bridge;
-    postAndWaitCreateBridgeTask(BLINK_FROM_HERE, testThread.get(), &bridge, &mainMock, this);
+    postAndWaitCreateBridgeTask(BLINK_FROM_HERE, testThread.get(), &bridge, &mainMock, &mockGL, this);
 
     // Register an alternate Logger for tracking hibernation events
     OwnPtr<MockLogger> mockLogger = adoptPtr(new MockLogger);
     MockLogger* mockLoggerPtr = mockLogger.get();
     bridge->setLoggerForTesting(mockLogger.release());
 
-    mainMock.fakeContextLost();
+    mockGL.setIsContextLost(true);
     // Test entering hibernation
     OwnPtr<WaitableEvent> hibernationAbortedEvent = adoptPtr(new WaitableEvent());
     EXPECT_CALL(*mockLoggerPtr, reportHibernationEvent(Canvas2DLayerBridge::HibernationScheduled));
@@ -1022,12 +1050,13 @@
 #endif
 {
     MockCanvasContext mainMock;
+    MockGLES2Interface mockGL;
     OwnPtr<WebThread> testThread = adoptPtr(Platform::current()->createThread("TestThread"));
 
     // The Canvas2DLayerBridge has to be created on the thread that will use it
     // to avoid WeakPtr thread check issues.
     Canvas2DLayerBridgePtr bridge;
-    postAndWaitCreateBridgeTask(BLINK_FROM_HERE, testThread.get(), &bridge, &mainMock, this);
+    postAndWaitCreateBridgeTask(BLINK_FROM_HERE, testThread.get(), &bridge, &mainMock, &mockGL, this);
 
     // Register an alternate Logger for tracking hibernation events
     OwnPtr<MockLogger> mockLogger = adoptPtr(new MockLogger);
@@ -1061,12 +1090,13 @@
 #endif
 {
     MockCanvasContext mainMock;
+    MockGLES2Interface mockGL;
     OwnPtr<WebThread> testThread = adoptPtr(Platform::current()->createThread("TestThread"));
 
     // The Canvas2DLayerBridge has to be created on the thread that will use it
     // to avoid WeakPtr thread check issues.
     Canvas2DLayerBridgePtr bridge;
-    postAndWaitCreateBridgeTask(BLINK_FROM_HERE, testThread.get(), &bridge, &mainMock, this);
+    postAndWaitCreateBridgeTask(BLINK_FROM_HERE, testThread.get(), &bridge, &mainMock, &mockGL, this);
 
     // Register an alternate Logger for tracking hibernation events
     OwnPtr<MockLogger> mockLogger = adoptPtr(new MockLogger);
diff --git a/third_party/WebKit/Source/platform/graphics/DEPS b/third_party/WebKit/Source/platform/graphics/DEPS
index 226f05e..2556ec9 100644
--- a/third_party/WebKit/Source/platform/graphics/DEPS
+++ b/third_party/WebKit/Source/platform/graphics/DEPS
@@ -4,4 +4,5 @@
     "+base/message_loop",
     "+cc",
     "-cc/blink",
+    "+gpu/command_buffer/client/gles2_interface.h",
 ]
diff --git a/third_party/WebKit/Source/platform/graphics/gpu/DEPS b/third_party/WebKit/Source/platform/graphics/gpu/DEPS
new file mode 100644
index 0000000..e264555
--- /dev/null
+++ b/third_party/WebKit/Source/platform/graphics/gpu/DEPS
@@ -0,0 +1,4 @@
+include_rules = [
+    # For tests only!
+    "+gpu/command_buffer/client/gles2_interface_stub.h",
+]
diff --git a/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.cpp b/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.cpp
index 9d2600b..3b361f7 100644
--- a/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.cpp
+++ b/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.cpp
@@ -30,6 +30,7 @@
 
 #include "platform/graphics/gpu/DrawingBuffer.h"
 
+#include "gpu/command_buffer/client/gles2_interface.h"
 #include "platform/RuntimeEnabledFeatures.h"
 #include "platform/TraceEvent.h"
 #include "platform/graphics/GraphicsLayer.h"
@@ -97,7 +98,8 @@
         return nullptr;
     }
 
-    OwnPtr<Extensions3DUtil> extensionsUtil = Extensions3DUtil::create(context.get());
+    gpu::gles2::GLES2Interface* gl = context->getGLES2Interface();
+    OwnPtr<Extensions3DUtil> extensionsUtil = Extensions3DUtil::create(context.get(), gl);
     if (!extensionsUtil->isValid()) {
         // This might be the first time we notice that the WebGraphicsContext3D is lost.
         return nullptr;
@@ -118,7 +120,7 @@
     if (discardFramebufferSupported)
         extensionsUtil->ensureExtensionEnabled("GL_EXT_discard_framebuffer");
 
-    RefPtr<DrawingBuffer> drawingBuffer = adoptRef(new DrawingBuffer(std::move(context), extensionsUtil.release(), multisampleSupported, discardFramebufferSupported, preserve, requestedAttributes));
+    RefPtr<DrawingBuffer> drawingBuffer = adoptRef(new DrawingBuffer(std::move(context), gl, extensionsUtil.release(), multisampleSupported, discardFramebufferSupported, preserve, requestedAttributes));
     if (!drawingBuffer->initialize(size)) {
         drawingBuffer->beginDestruction();
         return PassRefPtr<DrawingBuffer>();
@@ -131,12 +133,7 @@
     shouldFailDrawingBufferCreationForTesting = true;
 }
 
-DrawingBuffer::DrawingBuffer(PassOwnPtr<WebGraphicsContext3D> context,
-    PassOwnPtr<Extensions3DUtil> extensionsUtil,
-    bool multisampleExtensionSupported,
-    bool discardFramebufferSupported,
-    PreserveDrawingBuffer preserve,
-    WebGraphicsContext3D::Attributes requestedAttributes)
+DrawingBuffer::DrawingBuffer(PassOwnPtr<WebGraphicsContext3D> context, gpu::gles2::GLES2Interface* gl, PassOwnPtr<Extensions3DUtil> extensionsUtil, bool multisampleExtensionSupported, bool discardFramebufferSupported, PreserveDrawingBuffer preserve, WebGraphicsContext3D::Attributes requestedAttributes)
     : m_preserveDrawingBuffer(preserve)
     , m_scissorEnabled(false)
     , m_texture2DBinding(0)
@@ -144,6 +141,7 @@
     , m_readFramebufferBinding(0)
     , m_activeTextureUnit(GL_TEXTURE0)
     , m_context(std::move(context))
+    , m_gl(gl)
     , m_extensionsUtil(std::move(extensionsUtil))
     , m_size(-1, -1)
     , m_requestedAttributes(requestedAttributes)
@@ -320,7 +318,7 @@
 
 void DrawingBuffer::mailboxReleased(const WebExternalTextureMailbox& mailbox, bool lostResource)
 {
-    if (m_destructionInProgress || m_context->isContextLost() || lostResource || m_isHidden) {
+    if (m_destructionInProgress || m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR || lostResource || m_isHidden) {
         mailboxReleasedWithoutRecycling(mailbox);
         return;
     }
@@ -444,7 +442,7 @@
 
 bool DrawingBuffer::initialize(const IntSize& size)
 {
-    if (m_context->isContextLost()) {
+    if (m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR) {
         // Need to try to restore the context again later.
         return false;
     }
@@ -490,7 +488,7 @@
     }
     m_actualAttributes.antialias = multisample();
 
-    if (m_context->isContextLost()) {
+    if (m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR) {
         // It's possible that the drawing buffer allocation provokes a context loss, so check again just in case. http://crbug.com/512302
         return false;
     }
diff --git a/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.h b/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.h
index 5ea2af0..efdb7a3 100644
--- a/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.h
+++ b/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.h
@@ -46,11 +46,15 @@
 #include "wtf/OwnPtr.h"
 #include "wtf/PassOwnPtr.h"
 
+namespace gpu {
+namespace gles2 {
+class GLES2Interface;
+}
+}
+
 namespace WTF {
-
 class ArrayBufferContents;
-
-} // namespace WTF
+}
 
 namespace blink {
 
@@ -175,6 +179,7 @@
 protected: // For unittests
     DrawingBuffer(
         PassOwnPtr<WebGraphicsContext3D>,
+        gpu::gles2::GLES2Interface*,
         PassOwnPtr<Extensions3DUtil>,
         bool multisampleExtensionSupported,
         bool discardFramebufferSupported,
@@ -299,6 +304,7 @@
     GLenum m_activeTextureUnit;
 
     OwnPtr<WebGraphicsContext3D> m_context;
+    gpu::gles2::GLES2Interface* m_gl; // Lifetime is tied to the m_context.
     OwnPtr<Extensions3DUtil> m_extensionsUtil;
     IntSize m_size;
     WebGraphicsContext3D::Attributes m_requestedAttributes;
diff --git a/third_party/WebKit/Source/platform/graphics/gpu/DrawingBufferTest.cpp b/third_party/WebKit/Source/platform/graphics/gpu/DrawingBufferTest.cpp
index 7e9dc9f3..76d1b49 100644
--- a/third_party/WebKit/Source/platform/graphics/gpu/DrawingBufferTest.cpp
+++ b/third_party/WebKit/Source/platform/graphics/gpu/DrawingBufferTest.cpp
@@ -30,6 +30,7 @@
 
 #include "platform/graphics/gpu/DrawingBuffer.h"
 
+#include "gpu/command_buffer/client/gles2_interface_stub.h"
 #include "platform/RuntimeEnabledFeatures.h"
 #include "platform/graphics/ImageBuffer.h"
 #include "platform/graphics/UnacceleratedImageBufferSurface.h"
@@ -68,9 +69,12 @@
 
 } // namespace
 
+class GLES2InterfaceForTests : public gpu::gles2::GLES2InterfaceStub {
+};
+
 class WebGraphicsContext3DForTests : public MockWebGraphicsContext3D {
 public:
-    WebGraphicsContext3DForTests()
+    WebGraphicsContext3DForTests(PassOwnPtr<GLES2InterfaceForTests> contextGL)
         : MockWebGraphicsContext3D()
         , m_boundTexture(0)
         , m_boundTextureTarget(0)
@@ -78,6 +82,7 @@
         , m_mostRecentlyWaitedSyncToken(0)
         , m_currentImageId(1)
         , m_allowImageChromium(true)
+        , m_contextGL(std::move(contextGL))
     {
     }
 
@@ -188,6 +193,11 @@
         m_allowImageChromium = allow;
     }
 
+    gpu::gles2::GLES2Interface* getGLES2Interface() override
+    {
+        return m_contextGL.get();
+    }
+
 private:
     WebGLId m_boundTexture;
     WGC3Denum m_boundTextureTarget;
@@ -199,6 +209,7 @@
     HashMap<WGC3Duint, IntSize> m_imageSizes;
     HashMap<WGC3Duint, WebGLId> m_imageToTextureMap;
     bool m_allowImageChromium;
+    OwnPtr<GLES2InterfaceForTests> m_contextGL;
 };
 
 static const int initialWidth = 100;
@@ -207,12 +218,10 @@
 
 class DrawingBufferForTests : public DrawingBuffer {
 public:
-    static PassRefPtr<DrawingBufferForTests> create(PassOwnPtr<WebGraphicsContext3D> context,
-        const IntSize& size, PreserveDrawingBuffer preserve)
+    static PassRefPtr<DrawingBufferForTests> create(PassOwnPtr<WebGraphicsContext3D> context, gpu::gles2::GLES2Interface* gl, const IntSize& size, PreserveDrawingBuffer preserve)
     {
-        OwnPtr<Extensions3DUtil> extensionsUtil = Extensions3DUtil::create(context.get());
-        RefPtr<DrawingBufferForTests> drawingBuffer =
-            adoptRef(new DrawingBufferForTests(context, extensionsUtil.release(), preserve));
+        OwnPtr<Extensions3DUtil> extensionsUtil = Extensions3DUtil::create(context.get(), gl);
+        RefPtr<DrawingBufferForTests> drawingBuffer = adoptRef(new DrawingBufferForTests(context, gl, extensionsUtil.release(), preserve));
         if (!drawingBuffer->initialize(size)) {
             drawingBuffer->beginDestruction();
             return PassRefPtr<DrawingBufferForTests>();
@@ -220,10 +229,8 @@
         return drawingBuffer.release();
     }
 
-    DrawingBufferForTests(PassOwnPtr<WebGraphicsContext3D> context,
-        PassOwnPtr<Extensions3DUtil> extensionsUtil,
-        PreserveDrawingBuffer preserve)
-        : DrawingBuffer(context, extensionsUtil, false /* multisampleExtensionSupported */, false /* discardFramebufferSupported */, preserve, WebGraphicsContext3D::Attributes())
+    DrawingBufferForTests(PassOwnPtr<WebGraphicsContext3D> context, gpu::gles2::GLES2Interface* gl, PassOwnPtr<Extensions3DUtil> extensionsUtil, PreserveDrawingBuffer preserve)
+        : DrawingBuffer(context, gl, extensionsUtil, false /* multisampleExtensionSupported */, false /* discardFramebufferSupported */, preserve, WebGraphicsContext3D::Attributes())
         , m_live(0)
     { }
 
@@ -240,9 +247,11 @@
 protected:
     void SetUp() override
     {
-        OwnPtr<WebGraphicsContext3DForTests> context = adoptPtr(new WebGraphicsContext3DForTests);
+        OwnPtr<GLES2InterfaceForTests> gl = adoptPtr(new GLES2InterfaceForTests);
+        m_gl = gl.get();
+        OwnPtr<WebGraphicsContext3DForTests> context = adoptPtr(new WebGraphicsContext3DForTests(gl.release()));
         m_context = context.get();
-        m_drawingBuffer = DrawingBufferForTests::create(context.release(),
+        m_drawingBuffer = DrawingBufferForTests::create(context.release(), m_gl,
             IntSize(initialWidth, initialHeight), DrawingBuffer::Preserve);
     }
 
@@ -252,6 +261,7 @@
     }
 
     WebGraphicsContext3DForTests* m_context;
+    gpu::gles2::GLES2Interface* m_gl;
     RefPtr<DrawingBufferForTests> m_drawingBuffer;
 };
 
@@ -466,12 +476,14 @@
 protected:
     void SetUp() override
     {
-        OwnPtr<WebGraphicsContext3DForTests> context = adoptPtr(new WebGraphicsContext3DForTests);
+        OwnPtr<GLES2InterfaceForTests> gl = adoptPtr(new GLES2InterfaceForTests);
+        m_gl = gl.get();
+        OwnPtr<WebGraphicsContext3DForTests> context = adoptPtr(new WebGraphicsContext3DForTests(gl.release()));
         m_context = context.get();
         RuntimeEnabledFeatures::setWebGLImageChromiumEnabled(true);
         m_imageId0 = webContext()->nextImageIdToBeCreated();
         EXPECT_CALL(*webContext(), bindTexImage2DMock(m_imageId0)).Times(1);
-        m_drawingBuffer = DrawingBufferForTests::create(context.release(),
+        m_drawingBuffer = DrawingBufferForTests::create(context.release(), m_gl,
             IntSize(initialWidth, initialHeight), DrawingBuffer::Preserve);
         testing::Mock::VerifyAndClearExpectations(webContext());
     }
@@ -613,11 +625,14 @@
         MockWebGraphicsContext3D::getIntegerv(ptype, value);
     }
 
+    gpu::gles2::GLES2Interface* getGLES2Interface() override { return &m_contextGL; }
+
 private:
     WebGLId m_nextRenderBufferId;
     WebGLId m_stencilAttachment;
     WebGLId m_depthAttachment;
     WebGLId m_depthStencilAttachment;
+    gpu::gles2::GLES2InterfaceStub m_contextGL;
 };
 
 struct DepthStencilTestCase {
@@ -713,11 +728,13 @@
 protected:
     void SetUp() override
     {
-        OwnPtr<WebGraphicsContext3DForTests> context = adoptPtr(new WebGraphicsContext3DForTests);
+        OwnPtr<GLES2InterfaceForTests> gl = adoptPtr(new GLES2InterfaceForTests);
+        m_gl = gl.get();
+        OwnPtr<WebGraphicsContext3DForTests> context = adoptPtr(new WebGraphicsContext3DForTests(gl.release()));
         context->setAllowImageChromium(false);
         m_context = context.get();
         RuntimeEnabledFeatures::setWebGLImageChromiumEnabled(true);
-        m_drawingBuffer = DrawingBufferForTests::create(context.release(),
+        m_drawingBuffer = DrawingBufferForTests::create(context.release(), m_gl,
             IntSize(initialWidth, initialHeight), DrawingBuffer::Preserve);
     }
 
diff --git a/third_party/WebKit/Source/platform/graphics/gpu/Extensions3DUtil.cpp b/third_party/WebKit/Source/platform/graphics/gpu/Extensions3DUtil.cpp
index 47af1934..4941e8d 100644
--- a/third_party/WebKit/Source/platform/graphics/gpu/Extensions3DUtil.cpp
+++ b/third_party/WebKit/Source/platform/graphics/gpu/Extensions3DUtil.cpp
@@ -4,6 +4,7 @@
 
 #include "platform/graphics/gpu/Extensions3DUtil.h"
 
+#include "gpu/command_buffer/client/gles2_interface.h"
 #include "public/platform/WebGraphicsContext3D.h"
 #include "wtf/text/CString.h"
 #include "wtf/text/StringHash.h"
@@ -22,15 +23,16 @@
 
 } // anonymous namespace
 
-PassOwnPtr<Extensions3DUtil> Extensions3DUtil::create(WebGraphicsContext3D* context)
+PassOwnPtr<Extensions3DUtil> Extensions3DUtil::create(WebGraphicsContext3D* context, gpu::gles2::GLES2Interface* gl)
 {
-    OwnPtr<Extensions3DUtil> out = adoptPtr(new Extensions3DUtil(context));
+    OwnPtr<Extensions3DUtil> out = adoptPtr(new Extensions3DUtil(context, gl));
     out->initializeExtensions();
     return out.release();
 }
 
-Extensions3DUtil::Extensions3DUtil(WebGraphicsContext3D* context)
+Extensions3DUtil::Extensions3DUtil(WebGraphicsContext3D* context, gpu::gles2::GLES2Interface* gl)
     : m_context(context)
+    , m_gl(gl)
     , m_isValid(true)
 {
 }
@@ -41,7 +43,7 @@
 
 void Extensions3DUtil::initializeExtensions()
 {
-    if (m_context->isContextLost()) {
+    if (m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR) {
         // If the context is lost don't initialize the extension strings.
         // This will cause supportsExtension, ensureExtensionEnabled, and isExtensionEnabled to always return false.
         m_isValid = false;
diff --git a/third_party/WebKit/Source/platform/graphics/gpu/Extensions3DUtil.h b/third_party/WebKit/Source/platform/graphics/gpu/Extensions3DUtil.h
index ee6298c..0e36c32 100644
--- a/third_party/WebKit/Source/platform/graphics/gpu/Extensions3DUtil.h
+++ b/third_party/WebKit/Source/platform/graphics/gpu/Extensions3DUtil.h
@@ -15,6 +15,12 @@
 #include "wtf/text/StringHash.h"
 #include "wtf/text/WTFString.h"
 
+namespace gpu {
+namespace gles2 {
+class GLES2Interface;
+}
+}
+
 namespace blink {
 
 class WebGraphicsContext3D;
@@ -23,8 +29,8 @@
     USING_FAST_MALLOC(Extensions3DUtil);
     WTF_MAKE_NONCOPYABLE(Extensions3DUtil);
 public:
-    // Creates a new Extensions3DUtil. If the passed WebGraphicsContext3D has been spontaneously lost, returns null.
-    static PassOwnPtr<Extensions3DUtil> create(WebGraphicsContext3D*);
+    // Creates a new Extensions3DUtil. If the passed GLES2Interface has been spontaneously lost, returns null.
+    static PassOwnPtr<Extensions3DUtil> create(WebGraphicsContext3D*, gpu::gles2::GLES2Interface*);
     ~Extensions3DUtil();
 
     bool isValid() { return m_isValid; }
@@ -36,10 +42,11 @@
     static bool canUseCopyTextureCHROMIUM(GLenum destTarget, GLenum destFormat, GLenum destType, GLint level);
 
 private:
-    Extensions3DUtil(WebGraphicsContext3D*);
+    Extensions3DUtil(WebGraphicsContext3D*, gpu::gles2::GLES2Interface*);
     void initializeExtensions();
 
     WebGraphicsContext3D* m_context;
+    gpu::gles2::GLES2Interface* m_gl;
     HashSet<String> m_enabledExtensions;
     HashSet<String> m_requestableExtensions;
     bool m_isValid;
diff --git a/third_party/WebKit/Source/platform/graphics/gpu/SharedContextRateLimiter.cpp b/third_party/WebKit/Source/platform/graphics/gpu/SharedContextRateLimiter.cpp
index 45067a61..0fc1996 100644
--- a/third_party/WebKit/Source/platform/graphics/gpu/SharedContextRateLimiter.cpp
+++ b/third_party/WebKit/Source/platform/graphics/gpu/SharedContextRateLimiter.cpp
@@ -4,6 +4,7 @@
 
 #include "platform/graphics/gpu/SharedContextRateLimiter.h"
 
+#include "gpu/command_buffer/client/gles2_interface.h"
 #include "platform/graphics/gpu/Extensions3DUtil.h"
 #include "public/platform/Platform.h"
 #include "public/platform/WebGraphicsContext3D.h"
@@ -28,9 +29,9 @@
     if (!m_contextProvider)
         return;
 
-    WebGraphicsContext3D* context = m_contextProvider->context3d();
-    if (context && !context->isContextLost()) {
-        OwnPtr<Extensions3DUtil> extensionsUtil = Extensions3DUtil::create(context);
+    gpu::gles2::GLES2Interface* gl = m_contextProvider->contextGL();
+    if (gl && gl->GetGraphicsResetStatusKHR() == GL_NO_ERROR) {
+        OwnPtr<Extensions3DUtil> extensionsUtil = Extensions3DUtil::create(m_contextProvider->context3d(), gl);
         // TODO(junov): when the GLES 3.0 command buffer is ready, we could use fenceSync instead
         m_canUseSyncQueries = extensionsUtil->supportsExtension("GL_CHROMIUM_sync_query");
     }
@@ -41,11 +42,12 @@
     if (!m_contextProvider)
         return;
 
-    WebGraphicsContext3D* context = m_contextProvider->context3d();
+    gpu::gles2::GLES2Interface* gl = m_contextProvider->contextGL();
 
-    if (!context || context->isContextLost())
+    if (!gl || gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR)
         return;
 
+    WebGraphicsContext3D* context = m_contextProvider->context3d();
     m_queries.append(m_canUseSyncQueries ? context->createQueryEXT() : 0);
     if (m_canUseSyncQueries) {
         context->beginQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM, m_queries.last());
@@ -69,8 +71,9 @@
     if (!m_contextProvider)
         return;
 
-    WebGraphicsContext3D* context = m_contextProvider->context3d();
-    if (context && !context->isContextLost()) {
+    gpu::gles2::GLES2Interface* gl = m_contextProvider->contextGL();
+    if (gl && gl->GetGraphicsResetStatusKHR() == GL_NO_ERROR) {
+        WebGraphicsContext3D* context = m_contextProvider->context3d();
         while (m_queries.size() > 0) {
             context->deleteQueryEXT(m_queries.first());
             m_queries.removeFirst();
diff --git a/third_party/WebKit/Source/platform/graphics/test/DEPS b/third_party/WebKit/Source/platform/graphics/test/DEPS
new file mode 100644
index 0000000..67567cc
--- /dev/null
+++ b/third_party/WebKit/Source/platform/graphics/test/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+    "+gpu/command_buffer/client/gles2_interface_stub.h",
+]
diff --git a/third_party/WebKit/Source/platform/graphics/test/MockGLES2Interface.h b/third_party/WebKit/Source/platform/graphics/test/MockGLES2Interface.h
new file mode 100644
index 0000000..ecab6e01
--- /dev/null
+++ b/third_party/WebKit/Source/platform/graphics/test/MockGLES2Interface.h
@@ -0,0 +1,23 @@
+// 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 MockGLES2Interface_h
+#define MockGLES2Interface_h
+
+#include "gpu/command_buffer/client/gles2_interface_stub.h"
+
+class MockGLES2Interface : public gpu::gles2::GLES2InterfaceStub {
+public:
+    GLenum GetGraphicsResetStatusKHR() override
+    {
+        return m_contextLost ? GL_INVALID_OPERATION : GL_NO_ERROR;
+    }
+
+    void setIsContextLost(bool lost) { m_contextLost = lost; }
+
+private:
+    bool m_contextLost = false;
+};
+
+#endif // MockGLES2Interface_h
diff --git a/third_party/WebKit/Source/platform/graphics/test/MockWebGraphicsContext3D.h b/third_party/WebKit/Source/platform/graphics/test/MockWebGraphicsContext3D.h
index d41a810..ff7c637 100644
--- a/third_party/WebKit/Source/platform/graphics/test/MockWebGraphicsContext3D.h
+++ b/third_party/WebKit/Source/platform/graphics/test/MockWebGraphicsContext3D.h
@@ -47,8 +47,6 @@
 
     virtual void synthesizeGLError(WGC3Denum) { }
 
-    virtual bool isContextLost() { return m_contextLost; }
-
     virtual void* mapBufferSubDataCHROMIUM(WGC3Denum target, WGC3Dintptr offset, WGC3Dsizeiptr size, WGC3Denum access) { return 0; }
     virtual void unmapBufferSubDataCHROMIUM(const void*) { }
     virtual void* mapTexSubImage2DCHROMIUM(WGC3Denum target, WGC3Dint level, WGC3Dint xoffset, WGC3Dint yoffset, WGC3Dsizei width, WGC3Dsizei height, WGC3Denum format, WGC3Denum type, WGC3Denum access) { return 0; }
@@ -285,6 +283,9 @@
 
     virtual WebString getTranslatedShaderSourceANGLE(WebGLId) { return WebString(); }
 
+    // Don't use this, make a MockGLES2Interface instead.
+    virtual gpu::gles2::GLES2Interface* getGLES2Interface() { return nullptr; }
+
     void fakeContextLost() { m_contextLost = true; }
 protected:
     unsigned m_nextTextureId;
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollableArea.h b/third_party/WebKit/Source/platform/scroll/ScrollableArea.h
index 2d320b5..ff1a5aa 100644
--- a/third_party/WebKit/Source/platform/scroll/ScrollableArea.h
+++ b/third_party/WebKit/Source/platform/scroll/ScrollableArea.h
@@ -333,13 +333,11 @@
     unsigned m_verticalScrollbarNeedsPaintInvalidation : 1;
     unsigned m_scrollCornerNeedsPaintInvalidation : 1;
 
-    // There are 8 possible combinations of writing mode and direction. Scroll origin will be non-zero in the x or y axis
+    // There are 6 possible combinations of writing mode and direction. Scroll origin will be non-zero in the x or y axis
     // if there is any reversed direction or writing-mode. The combinations are:
     // writing-mode / direction     scrollOrigin.x() set    scrollOrigin.y() set
     // horizontal-tb / ltr          NO                      NO
     // horizontal-tb / rtl          YES                     NO
-    // horizontal-bt / ltr          NO                      YES
-    // horizontal-bt / rtl          YES                     YES
     // vertical-lr / ltr            NO                      NO
     // vertical-lr / rtl            NO                      YES
     // vertical-rl / ltr            YES                     NO
diff --git a/third_party/WebKit/Source/platform/v8_inspector/InjectedScript.cpp b/third_party/WebKit/Source/platform/v8_inspector/InjectedScript.cpp
index aa5e01f8..8209374 100644
--- a/third_party/WebKit/Source/platform/v8_inspector/InjectedScript.cpp
+++ b/third_party/WebKit/Source/platform/v8_inspector/InjectedScript.cpp
@@ -169,61 +169,6 @@
     *result = makeEvalCall(errorString, function, wasThrown, exceptionDetails);
 }
 
-void InjectedScript::restartFrame(ErrorString* errorString, v8::Local<v8::Object> callFrames, const String16& callFrameId)
-{
-    v8::HandleScope handles(m_isolate);
-    V8FunctionCall function(m_client, context(), v8Value(), "restartFrame");
-    function.appendArgument(callFrames);
-    function.appendArgument(callFrameId);
-    OwnPtr<protocol::Value> resultValue = makeCall(function);
-    if (resultValue) {
-        if (resultValue->type() == protocol::Value::TypeString) {
-            resultValue->asString(errorString);
-        } else {
-            bool value;
-            ASSERT_UNUSED(value, resultValue->asBoolean(&value) && value);
-        }
-        return;
-    }
-    *errorString = "Internal error";
-}
-
-void InjectedScript::setVariableValue(ErrorString* errorString,
-    v8::Local<v8::Object> callFrames,
-    const protocol::Maybe<String16>& callFrameIdOpt,
-    const protocol::Maybe<String16>&  functionObjectIdOpt,
-    int scopeNumber,
-    const String16& variableName,
-    const String16& newValueStr)
-{
-    v8::HandleScope handles(m_isolate);
-    V8FunctionCall function(m_client, context(), v8Value(), "setVariableValue");
-    if (callFrameIdOpt.isJust()) {
-        function.appendArgument(callFrames);
-        function.appendArgument(callFrameIdOpt.fromJust());
-    } else {
-        function.appendArgument(false);
-        function.appendArgument(false);
-    }
-    if (functionObjectIdOpt.isJust())
-        function.appendArgument(functionObjectIdOpt.fromJust());
-    else
-        function.appendArgument(false);
-    function.appendArgument(scopeNumber);
-    function.appendArgument(variableName);
-    function.appendArgument(newValueStr);
-    OwnPtr<protocol::Value> resultValue = makeCall(function);
-    if (!resultValue) {
-        *errorString = "Internal error";
-        return;
-    }
-    if (resultValue->type() == protocol::Value::TypeString) {
-        resultValue->asString(errorString);
-        return;
-    }
-    // Normal return.
-}
-
 void InjectedScript::getFunctionDetails(ErrorString* errorString, const String16& functionId, OwnPtr<FunctionDetails>* result)
 {
     v8::HandleScope handles(m_isolate);
@@ -531,4 +476,35 @@
     m_manager->discardInjectedScript(m_contextId);
 }
 
+v8::MaybeLocal<v8::Value> InjectedScript::resolveCallArgument(ErrorString* errorString, protocol::Runtime::CallArgument* callArgument)
+{
+    if (callArgument->hasObjectId()) {
+        OwnPtr<RemoteObjectId> remoteObjectId = RemoteObjectId::parse(errorString, callArgument->getObjectId(""));
+        if (!remoteObjectId)
+            return v8::MaybeLocal<v8::Value>();
+        if (remoteObjectId->contextId() != m_contextId) {
+            *errorString = "Argument should belong to the same JavaScript world as target object";
+            return v8::MaybeLocal<v8::Value>();
+        }
+        v8::Local<v8::Value> object = findObject(*remoteObjectId);
+        if (object.IsEmpty()) {
+            *errorString = "Could not find object with given id";
+            return v8::MaybeLocal<v8::Value>();
+        }
+        return object;
+    }
+    if (callArgument->hasValue()) {
+        String16 value = callArgument->getValue(nullptr)->toJSONString();
+        if (callArgument->getType(String16()) == "number")
+            value = "Number(" + value + ")";
+        v8::Local<v8::Value> object;
+        if (!m_client->compileAndRunInternalScript(toV8String(m_isolate, value)).ToLocal(&object)) {
+            *errorString = "Couldn't parse value object in call argument";
+            return v8::MaybeLocal<v8::Value>();
+        }
+        return object;
+    }
+    return v8::Undefined(m_isolate);
+}
+
 } // namespace blink
diff --git a/third_party/WebKit/Source/platform/v8_inspector/InjectedScript.h b/third_party/WebKit/Source/platform/v8_inspector/InjectedScript.h
index e94c78e..11cda71 100644
--- a/third_party/WebKit/Source/platform/v8_inspector/InjectedScript.h
+++ b/third_party/WebKit/Source/platform/v8_inspector/InjectedScript.h
@@ -85,8 +85,6 @@
         OwnPtr<protocol::Runtime::RemoteObject>* result,
         Maybe<bool>* wasThrown,
         Maybe<protocol::Runtime::ExceptionDetails>*);
-    void restartFrame(ErrorString*, v8::Local<v8::Object> callFrames, const String16& callFrameId);
-    void setVariableValue(ErrorString*, v8::Local<v8::Object> callFrames, const Maybe<String16>& callFrameIdOpt, const Maybe<String16>& functionObjectIdOpt, int scopeNumber, const String16& variableName, const String16& newValueStr);
     void getFunctionDetails(ErrorString*, const String16& functionId, OwnPtr<protocol::Debugger::FunctionDetails>* result);
     void getCollectionEntries(ErrorString*, const String16& objectId, OwnPtr<protocol::Array<protocol::Debugger::CollectionEntry>>* result);
     void getProperties(ErrorString*, const String16& objectId, bool ownProperties, bool accessorPropertiesOnly, bool generatePreview, OwnPtr<protocol::Array<protocol::Runtime::PropertyDescriptor>>* result, Maybe<protocol::Runtime::ExceptionDetails>*);
@@ -112,6 +110,8 @@
     v8::Local<v8::Context> context() const;
     void dispose();
 
+    v8::MaybeLocal<v8::Value> resolveCallArgument(ErrorString*, protocol::Runtime::CallArgument*);
+
 private:
     friend InjectedScript* InjectedScriptManager::injectedScriptFor(v8::Local<v8::Context>);
     InjectedScript(InjectedScriptManager*, v8::Local<v8::Context>, v8::Local<v8::Object>, V8DebuggerClient*, PassOwnPtr<InjectedScriptNative>, int contextId);
diff --git a/third_party/WebKit/Source/platform/v8_inspector/InjectedScriptSource.js b/third_party/WebKit/Source/platform/v8_inspector/InjectedScriptSource.js
index ff7566a..52df626 100644
--- a/third_party/WebKit/Source/platform/v8_inspector/InjectedScriptSource.js
+++ b/third_party/WebKit/Source/platform/v8_inspector/InjectedScriptSource.js
@@ -875,52 +875,6 @@
     },
 
     /**
-     * @param {!JavaScriptCallFrame} topCallFrame
-     * @param {string} callFrameId
-     * @return {*}
-     */
-    restartFrame: function(topCallFrame, callFrameId)
-    {
-        var callFrame = this._callFrameForId(topCallFrame, callFrameId);
-        if (!callFrame)
-            return "Could not find call frame with given id";
-        return callFrame.restart();
-    },
-
-    /**
-     * Either callFrameId or functionObjectId must be specified.
-     * @param {!JavaScriptCallFrame} topCallFrame
-     * @param {string|boolean} callFrameId or false
-     * @param {string|boolean} functionObjectId or false
-     * @param {number} scopeNumber
-     * @param {string} variableName
-     * @param {string} newValueJsonString RuntimeAgent.CallArgument structure serialized as string
-     * @return {string|undefined} undefined if success or an error message
-     */
-    setVariableValue: function(topCallFrame, callFrameId, functionObjectId, scopeNumber, variableName, newValueJsonString)
-    {
-        try {
-            var newValueJson = /** @type {!RuntimeAgent.CallArgument} */ (InjectedScriptHost.eval("(" + newValueJsonString + ")"));
-            var resolvedValue = this._resolveCallArgument(newValueJson);
-            if (typeof callFrameId === "string") {
-                var callFrame = this._callFrameForId(topCallFrame, callFrameId);
-                if (!callFrame)
-                    return "Could not find call frame with given id";
-                callFrame.setVariableValue(scopeNumber, variableName, resolvedValue)
-            } else {
-                var parsedFunctionId = this._parseObjectId(/** @type {string} */ (functionObjectId));
-                var func = this._objectForId(parsedFunctionId);
-                if (typeof func !== "function")
-                    return "Could not resolve function by id";
-                InjectedScriptHost.setFunctionVariableValue(func, scopeNumber, variableName, resolvedValue);
-            }
-        } catch (e) {
-            return toString(e);
-        }
-        return undefined;
-    },
-
-    /**
      * @return {!CommandLineAPI}
      */
     commandLineAPI: function()
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerAgentImpl.cpp b/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerAgentImpl.cpp
index 0bcc44ca..8fa34af 100644
--- a/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerAgentImpl.cpp
+++ b/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerAgentImpl.cpp
@@ -643,9 +643,24 @@
         return;
 
     v8::HandleScope scope(m_isolate);
-    v8::Local<v8::Object> callStack = m_currentCallStack.Get(m_isolate);
-    injectedScript->restartFrame(errorString, callStack, callFrameId);
+    v8::Local<v8::Context> localContext = injectedScript->context();
+
+    v8::TryCatch tryCatch(m_isolate);
+
+    OwnPtr<JavaScriptCallFrame> javaScriptCallFrame = debugger().callFrameNoScopes(remoteId->frameOrdinal());
+    if (!javaScriptCallFrame) {
+        *errorString = "Could not find call frame with given id";
+        return;
+    }
+    v8::Local<v8::Value> resultValue;
+    v8::Local<v8::Boolean> result;
+    if (!javaScriptCallFrame->restart().ToLocal(&resultValue) || tryCatch.HasCaught() || !resultValue->ToBoolean(localContext).ToLocal(&result) || !result->Value()) {
+        *errorString = "Internal error";
+        return;
+    }
+
     m_currentCallStack.Reset(m_isolate, debugger().currentCallFrames());
+
     *newCallFrames = currentCallFrames();
     *asyncStackTrace = currentAsyncStackTrace();
 }
@@ -921,39 +936,39 @@
 void V8DebuggerAgentImpl::setVariableValue(ErrorString* errorString,
     int scopeNumber,
     const String16& variableName,
-    PassOwnPtr<protocol::Runtime::CallArgument> newValue,
-    const Maybe<String16>& callFrameId,
-    const Maybe<String16>& functionObjectId)
+    PassOwnPtr<protocol::Runtime::CallArgument> newValueArgument,
+    const String16& callFrameId)
 {
     if (!checkEnabled(errorString))
         return;
-    InjectedScript* injectedScript = nullptr;
-    if (callFrameId.isJust()) {
-        if (!isPaused() || m_currentCallStack.IsEmpty()) {
-            *errorString = "Attempt to access callframe when debugger is not on pause";
-            return;
-        }
-        OwnPtr<RemoteCallFrameId> remoteId = RemoteCallFrameId::parse(errorString, callFrameId.fromJust());
-        if (!remoteId)
-            return;
-        injectedScript = m_injectedScriptManager->findInjectedScript(errorString, remoteId.get());
-        if (!injectedScript)
-            return;
-    } else if (functionObjectId.isJust()) {
-        OwnPtr<RemoteObjectId> remoteId = RemoteObjectId::parse(errorString, functionObjectId.fromJust());
-        if (!remoteId)
-            return;
-        injectedScript = m_injectedScriptManager->findInjectedScript(errorString, remoteId.get());
-        if (!injectedScript)
-            return;
-    } else {
-        *errorString = "Either call frame or function object must be specified";
+    if (!isPaused() || m_currentCallStack.IsEmpty()) {
+        *errorString = "Attempt to access callframe when debugger is not on pause";
         return;
     }
-    String16 newValueString = protocol::toValue(newValue.get())->toJSONString();
+    OwnPtr<RemoteCallFrameId> remoteId = RemoteCallFrameId::parse(errorString, callFrameId);
+    if (!remoteId)
+        return;
+    InjectedScript* injectedScript = m_injectedScriptManager->findInjectedScript(errorString, remoteId.get());
+    if (!injectedScript)
+        return;
+
     v8::HandleScope scope(m_isolate);
-    v8::Local<v8::Object> currentCallStack = m_currentCallStack.Get(m_isolate);
-    injectedScript->setVariableValue(errorString, currentCallStack, callFrameId, functionObjectId, scopeNumber, variableName, newValueString);
+    v8::TryCatch tryCatch(m_isolate);
+
+    v8::Local<v8::Value> newValue;
+    if (!injectedScript->resolveCallArgument(errorString, newValueArgument.get()).ToLocal(&newValue))
+        return;
+
+    OwnPtr<JavaScriptCallFrame> javaScriptCallFrame = debugger().callFrameNoScopes(remoteId->frameOrdinal());
+    if (!javaScriptCallFrame) {
+        *errorString = "Could not find call frame with given id";
+        return;
+    }
+    v8::MaybeLocal<v8::Value> result = javaScriptCallFrame->setVariableValue(scopeNumber, toV8String(m_isolate, variableName), newValue);
+    if (tryCatch.HasCaught() || result.IsEmpty()) {
+        *errorString = "Internal error";
+        return;
+    }
 }
 
 void V8DebuggerAgentImpl::setAsyncCallStackDepth(ErrorString* errorString, int depth)
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerAgentImpl.h b/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerAgentImpl.h
index 827ccc7..127a8ee 100644
--- a/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerAgentImpl.h
+++ b/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerAgentImpl.h
@@ -136,8 +136,7 @@
         int scopeNumber,
         const String16& variableName,
         PassOwnPtr<protocol::Runtime::CallArgument> newValue,
-        const Maybe<String16>& callFrame,
-        const Maybe<String16>& functionObjectId) override;
+        const String16& callFrame) override;
     void setAsyncCallStackDepth(ErrorString*, int depth) override;
     void enablePromiseTracker(ErrorString*,
         const Maybe<bool>& captureStacks) override;
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8InjectedScriptHost.cpp b/third_party/WebKit/Source/platform/v8_inspector/V8InjectedScriptHost.cpp
index 11a19cc9..1424ccf 100644
--- a/third_party/WebKit/Source/platform/v8_inspector/V8InjectedScriptHost.cpp
+++ b/third_party/WebKit/Source/platform/v8_inspector/V8InjectedScriptHost.cpp
@@ -346,22 +346,6 @@
     v8SetReturnValue(info, wrappedResult);
 }
 
-void V8InjectedScriptHost::setFunctionVariableValueCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
-{
-    if (info.Length() < 4 || !info[0]->IsFunction() || !info[1]->IsInt32() || !info[2]->IsString())
-        return;
-
-    v8::Local<v8::Value> functionValue = info[0];
-    int scopeIndex = info[1].As<v8::Int32>()->Value();
-    String16 variableName = toProtocolStringWithTypeCheck(info[2]);
-    v8::Local<v8::Value> newValue = info[3];
-
-    InjectedScriptHost* host = V8InjectedScriptHost::unwrap(info.GetIsolate()->GetCurrentContext(), info.Holder());
-    if (!host->debugger())
-        return;
-    v8SetReturnValue(info, host->debugger()->setFunctionVariableValue(functionValue, scopeIndex, variableName, newValue));
-}
-
 static bool getFunctionLocation(const v8::FunctionCallbackInfo<v8::Value>& info, String16* scriptId, int* lineNumber, int* columnNumber)
 {
     if (info.Length() < 1 || !info[0]->IsFunction())
@@ -580,7 +564,6 @@
     {"callFunction", V8InjectedScriptHost::callFunctionCallback},
     {"suppressWarningsAndCallFunction", V8InjectedScriptHost::suppressWarningsAndCallFunctionCallback},
     {"setNonEnumProperty", V8InjectedScriptHost::setNonEnumPropertyCallback},
-    {"setFunctionVariableValue", V8InjectedScriptHost::setFunctionVariableValueCallback},
     {"bind", V8InjectedScriptHost::bindCallback},
     {"objectForId", V8InjectedScriptHost::objectForIdCallback},
     {"idToObjectGroupName", V8InjectedScriptHost::idToObjectGroupNameCallback},
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8JavaScriptCallFrame.cpp b/third_party/WebKit/Source/platform/v8_inspector/V8JavaScriptCallFrame.cpp
index b6801001..f38f84c 100644
--- a/third_party/WebKit/Source/platform/v8_inspector/V8JavaScriptCallFrame.cpp
+++ b/third_party/WebKit/Source/platform/v8_inspector/V8JavaScriptCallFrame.cpp
@@ -99,29 +99,6 @@
     info.GetReturnValue().Set(impl->evaluateWithExceptionDetails(info[0], info[1]));
 }
 
-void restartMethodCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
-{
-    JavaScriptCallFrame* impl = V8JavaScriptCallFrame::unwrap(info.GetIsolate()->GetCurrentContext(), info.Holder());
-    v8::MaybeLocal<v8::Value> result = impl->restart();
-    v8::Local<v8::Value> value;
-    if (result.ToLocal(&value))
-        info.GetReturnValue().Set(value);
-}
-
-void setVariableValueMethodCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
-{
-    JavaScriptCallFrame* impl = V8JavaScriptCallFrame::unwrap(info.GetIsolate()->GetCurrentContext(), info.Holder());
-    v8::Maybe<int32_t> maybeScopeIndex = info[0]->Int32Value(info.GetIsolate()->GetCurrentContext());
-    if (maybeScopeIndex.IsNothing())
-        return;
-    int scopeIndex = maybeScopeIndex.FromJust();
-    v8::MaybeLocal<v8::Value> result = impl->setVariableValue(scopeIndex, info[1], info[2]);
-    v8::Local<v8::Value> value;
-    if (result.ToLocal(&value))
-        info.GetReturnValue().Set(value);
-
-}
-
 void scopeTypeMethodCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
 {
     JavaScriptCallFrame* impl = V8JavaScriptCallFrame::unwrap(info.GetIsolate()->GetCurrentContext(), info.Holder());
@@ -184,8 +161,6 @@
 
 const JavaScriptCallFrameWrapper::V8MethodConfiguration V8JavaScriptCallFrameMethods[] = {
     {"evaluateWithExceptionDetails", evaluateWithExceptionDetailsMethodCallback},
-    {"restart", restartMethodCallback},
-    {"setVariableValue", setVariableValueMethodCallback},
     {"scopeType", scopeTypeMethodCallback},
     {"scopeName", scopeNameMethodCallback},
     {"scopeStartLocation", scopeStartLocationMethodCallback},
diff --git a/third_party/WebKit/Source/platform/v8_inspector/injected_script_externs.js b/third_party/WebKit/Source/platform/v8_inspector/injected_script_externs.js
index 8a0323d0..4d5cdbf 100644
--- a/third_party/WebKit/Source/platform/v8_inspector/injected_script_externs.js
+++ b/third_party/WebKit/Source/platform/v8_inspector/injected_script_externs.js
@@ -128,15 +128,6 @@
 InjectedScriptHostClass.prototype.setNonEnumProperty = function(obj, key, value) {}
 
 /**
- * @param {!Function} functionObject
- * @param {number} scopeIndex
- * @param {string} variableName
- * @param {*} newValue
- * @return {*}
- */
-InjectedScriptHostClass.prototype.setFunctionVariableValue = function(functionObject, scopeIndex, variableName, newValue) {}
-
-/**
  * @param {*} value
  * @param {string} groupName
  * @return {number}
@@ -195,19 +186,6 @@
 JavaScriptCallFrame.prototype.evaluateWithExceptionDetails = function(script, scopeExtension) {}
 
 /**
- * @return {*}
- */
-JavaScriptCallFrame.prototype.restart = function() {}
-
-/**
- * @param {number=} scopeIndex
- * @param {?string=} variableName
- * @param {*=} newValue
- * @return {*}
- */
-JavaScriptCallFrame.prototype.setVariableValue = function(scopeIndex, variableName, newValue) {}
-
-/**
  * @param {number} scopeIndex
  * @return {number}
  */
diff --git a/third_party/WebKit/Source/web/AssociatedURLLoader.cpp b/third_party/WebKit/Source/web/AssociatedURLLoader.cpp
index 71ab8d9d..570718ff 100644
--- a/third_party/WebKit/Source/web/AssociatedURLLoader.cpp
+++ b/third_party/WebKit/Source/web/AssociatedURLLoader.cpp
@@ -93,7 +93,7 @@
         if (equalIgnoringCase(headerName, "access-control-expose-headers"))
             parseAccessControlExposeHeadersAllowList(value, m_exposedHeaders);
         else if (!isOnAccessControlResponseHeaderWhitelist(headerName))
-            m_blockedHeaders.add(name);
+            m_blockedHeaders.add(static_cast<String>(name));
     }
 }
 
diff --git a/third_party/WebKit/Source/web/BUILD.gn b/third_party/WebKit/Source/web/BUILD.gn
index 1df6a315..edeb26e 100644
--- a/third_party/WebKit/Source/web/BUILD.gn
+++ b/third_party/WebKit/Source/web/BUILD.gn
@@ -95,6 +95,7 @@
     "//base:i18n",
     "//base/test:test_support",
     "//content/test:test_support",
+    "//gpu:test_support",
     "//testing/gmock",
     "//testing/gtest",
     "//third_party/WebKit/Source/core",
diff --git a/third_party/WebKit/Source/web/web_tests.gyp b/third_party/WebKit/Source/web/web_tests.gyp
index abe3a93..611dde3 100644
--- a/third_party/WebKit/Source/web/web_tests.gyp
+++ b/third_party/WebKit/Source/web/web_tests.gyp
@@ -56,6 +56,7 @@
                 '<(DEPTH)/base/base.gyp:base',
                 '<(DEPTH)/base/base.gyp:base_i18n',
                 '<(DEPTH)/base/base.gyp:test_support_base',
+                '<(DEPTH)/gpu/gpu.gyp:gpu_unittest_utils',
                 '<(DEPTH)/testing/gmock.gyp:gmock',
                 '<(DEPTH)/testing/gtest.gyp:gtest',
                 '<(DEPTH)/third_party/libwebp/libwebp.gyp:libwebp',
diff --git a/third_party/WebKit/Source/wtf/HashSet.h b/third_party/WebKit/Source/wtf/HashSet.h
index 59fd57b..752a4c58 100644
--- a/third_party/WebKit/Source/wtf/HashSet.h
+++ b/third_party/WebKit/Source/wtf/HashSet.h
@@ -93,7 +93,8 @@
 
     // The return value is a pair of an iterator to the new value's location,
     // and a bool that is true if an new entry was added.
-    AddResult add(ValuePassInType);
+    template <typename IncomingValueType>
+    AddResult add(IncomingValueType&&);
 
     // An alternate version of add() that finds the object by hashing and
     // comparing with some other type, to avoid the cost of type conversion if
@@ -101,8 +102,8 @@
     // following function members:
     //   static unsigned hash(const T&);
     //   static bool equal(const ValueType&, const T&);
-    //   static translate(ValueType&, const T&, unsigned hashCode);
-    template <typename HashTranslator, typename T> AddResult add(const T&);
+    //   static translate(ValueType&, T&&, unsigned hashCode);
+    template <typename HashTranslator, typename T> AddResult addWithTranslator(T&&);
 
     void remove(ValuePeekInType);
     void remove(iterator);
@@ -132,9 +133,9 @@
     STATIC_ONLY(HashSetTranslatorAdapter);
     template <typename T> static unsigned hash(const T& key) { return Translator::hash(key); }
     template <typename T, typename U> static bool equal(const T& a, const U& b) { return Translator::equal(a, b); }
-    template <typename T, typename U> static void translate(T& location, const U& key, const U&, unsigned hashCode)
+    template <typename T, typename U, typename V> static void translate(T& location, U&& key, const V&, unsigned hashCode)
     {
-        Translator::translate(location, key, hashCode);
+        Translator::translate(location, std::forward<U>(key), hashCode);
     }
 };
 
@@ -196,17 +197,19 @@
 }
 
 template <typename T, typename U, typename V, typename W>
-inline typename HashSet<T, U, V, W>::AddResult HashSet<T, U, V, W>::add(ValuePassInType value)
+template <typename IncomingValueType>
+inline typename HashSet<T, U, V, W>::AddResult HashSet<T, U, V, W>::add(IncomingValueType&& value)
 {
-    return m_impl.add(value);
+    return m_impl.add(std::forward<IncomingValueType>(value));
 }
 
 template <typename Value, typename HashFunctions, typename Traits, typename Allocator>
 template <typename HashTranslator, typename T>
 inline typename HashSet<Value, HashFunctions, Traits, Allocator>::AddResult
-HashSet<Value, HashFunctions, Traits, Allocator>::add(const T& value)
+HashSet<Value, HashFunctions, Traits, Allocator>::addWithTranslator(T&& value)
 {
-    return m_impl.template addPassingHashCode<HashSetTranslatorAdapter<HashTranslator>>(value, value);
+    // Forward only the first argument, because the second argument isn't actually used in HashSetTranslatorAdapter.
+    return m_impl.template addPassingHashCode<HashSetTranslatorAdapter<HashTranslator>>(std::forward<T>(value), value);
 }
 
 template <typename T, typename U, typename V, typename W>
diff --git a/third_party/WebKit/Source/wtf/HashSetTest.cpp b/third_party/WebKit/Source/wtf/HashSetTest.cpp
index b21026b8..87db991 100644
--- a/third_party/WebKit/Source/wtf/HashSetTest.cpp
+++ b/third_party/WebKit/Source/wtf/HashSetTest.cpp
@@ -266,6 +266,129 @@
     EXPECT_EQ(0, counter);
 }
 
+class MoveOnly {
+public:
+    // kEmpty and kDeleted have special meanings when MoveOnly is used as the key of a hash table.
+    enum {
+        kEmpty = 0,
+        kDeleted = -1,
+        kMovedOut = -2
+    };
+
+    explicit MoveOnly(int value = kEmpty, int id = 0) : m_value(value), m_id(id) { }
+    MoveOnly(MoveOnly&& other)
+        : m_value(other.m_value)
+        , m_id(other.m_id)
+    {
+        other.m_value = kMovedOut;
+        other.m_id = 0;
+    }
+    MoveOnly& operator=(MoveOnly&& other)
+    {
+        m_value = other.m_value;
+        m_id = other.m_id;
+        other.m_value = kMovedOut;
+        other.m_id = 0;
+        return *this;
+    }
+
+    int value() const { return m_value; }
+    // id() is used for distinguishing MoveOnlys with the same value().
+    int id() const { return m_id; }
+
+private:
+    MoveOnly(const MoveOnly&) = delete;
+    MoveOnly& operator=(const MoveOnly&) = delete;
+
+    int m_value;
+    int m_id;
+};
+
+struct MoveOnlyHashTraits : public GenericHashTraits<MoveOnly> {
+    // This is actually true, but we pretend that it's false to disable the optimization.
+    static const bool emptyValueIsZero = false;
+
+    static const bool hasIsEmptyValueFunction = true;
+    static bool isEmptyValue(const MoveOnly& value) { return value.value() == MoveOnly::kEmpty; }
+    static void constructDeletedValue(MoveOnly& slot, bool) { slot = MoveOnly(MoveOnly::kDeleted); }
+    static bool isDeletedValue(const MoveOnly& value) { return value.value() == MoveOnly::kDeleted; }
+};
+
+struct MoveOnlyHash {
+    static unsigned hash(const MoveOnly& value) { return DefaultHash<int>::Hash::hash(value.value()); }
+    static bool equal(const MoveOnly& left, const MoveOnly& right)
+    {
+        return DefaultHash<int>::Hash::equal(left.value(), right.value());
+    }
+    static const bool safeToCompareToEmptyOrDeleted = true;
+};
+
+} // anonymous namespace
+
+template <>
+struct HashTraits<MoveOnly> : public MoveOnlyHashTraits { };
+
+template <>
+struct DefaultHash<MoveOnly> {
+    using Hash = MoveOnlyHash;
+};
+
+namespace {
+
+TEST(HashSetTest, MoveOnlyValue)
+{
+    using TheSet = HashSet<MoveOnly>;
+    TheSet set;
+    {
+        TheSet::AddResult addResult = set.add(MoveOnly(1, 1));
+        EXPECT_TRUE(addResult.isNewEntry);
+        EXPECT_EQ(1, addResult.storedValue->value());
+        EXPECT_EQ(1, addResult.storedValue->id());
+    }
+    auto iter = set.find(MoveOnly(1));
+    ASSERT_TRUE(iter != set.end());
+    EXPECT_EQ(1, iter->value());
+
+    iter = set.find(MoveOnly(2));
+    EXPECT_TRUE(iter == set.end());
+
+    for (int i = 2; i < 32; ++i) {
+        TheSet::AddResult addResult = set.add(MoveOnly(i, i));
+        EXPECT_TRUE(addResult.isNewEntry);
+        EXPECT_EQ(i, addResult.storedValue->value());
+        EXPECT_EQ(i, addResult.storedValue->id());
+    }
+
+    iter = set.find(MoveOnly(1));
+    ASSERT_TRUE(iter != set.end());
+    EXPECT_EQ(1, iter->value());
+    EXPECT_EQ(1, iter->id());
+
+    iter = set.find(MoveOnly(7));
+    ASSERT_TRUE(iter != set.end());
+    EXPECT_EQ(7, iter->value());
+    EXPECT_EQ(7, iter->id());
+
+    {
+        TheSet::AddResult addResult = set.add(MoveOnly(7, 777)); // With different ID for identification.
+        EXPECT_FALSE(addResult.isNewEntry);
+        EXPECT_EQ(7, addResult.storedValue->value());
+        EXPECT_EQ(7, addResult.storedValue->id());
+    }
+
+    set.remove(MoveOnly(11));
+    iter = set.find(MoveOnly(11));
+    EXPECT_TRUE(iter == set.end());
+
+    MoveOnly thirteen(set.take(MoveOnly(13)));
+    EXPECT_EQ(13, thirteen.value());
+    EXPECT_EQ(13, thirteen.id());
+    iter = set.find(MoveOnly(13));
+    EXPECT_TRUE(iter == set.end());
+
+    set.clear();
+}
+
 } // anonymous namespace
 
 } // namespace WTF
diff --git a/third_party/WebKit/Source/wtf/HashTable.h b/third_party/WebKit/Source/wtf/HashTable.h
index bc20680..373dbda 100644
--- a/third_party/WebKit/Source/wtf/HashTable.h
+++ b/third_party/WebKit/Source/wtf/HashTable.h
@@ -456,16 +456,17 @@
 
     void reserveCapacityForSize(unsigned size);
 
-    AddResult add(ValuePassInType value)
+    template <typename IncomingValueType>
+    AddResult add(IncomingValueType&& value)
     {
-        return add<IdentityTranslatorType>(Extractor::extract(value), value);
+        return add<IdentityTranslatorType>(Extractor::extract(value), std::forward<IncomingValueType>(value));
     }
 
     // A special version of add() that finds the object by hashing and comparing
     // with some other type, to avoid the cost of type conversion if the object
     // is already in the table.
     template <typename HashTranslator, typename T, typename Extra> AddResult add(T&& key, Extra&&);
-    template <typename HashTranslator, typename T, typename Extra> AddResult addPassingHashCode(const T& key, const Extra&);
+    template <typename HashTranslator, typename T, typename Extra> AddResult addPassingHashCode(T&& key, Extra&&);
 
     iterator find(KeyPeekInType key) { return find<IdentityTranslatorType>(key); }
     const_iterator find(KeyPeekInType key) const { return find<IdentityTranslatorType>(key); }
@@ -863,7 +864,7 @@
 
 template <typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits, typename Allocator>
 template <typename HashTranslator, typename T, typename Extra>
-typename HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>::AddResult HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>::addPassingHashCode(const T& key, const Extra& extra)
+typename HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>::AddResult HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>::addPassingHashCode(T&& key, Extra&& extra)
 {
     ASSERT(!m_accessForbidden);
     ASSERT(Allocator::isAllocationAllowed());
@@ -886,7 +887,7 @@
         --m_deletedCount;
     }
 
-    HashTranslator::translate(*entry, key, extra, h);
+    HashTranslator::translate(*entry, std::forward<T>(key), std::forward<Extra>(extra), h);
     ASSERT(!isEmptyOrDeletedBucket(*entry));
 
     ++m_keyCount;
diff --git a/third_party/WebKit/Source/wtf/ListHashSetTest.cpp b/third_party/WebKit/Source/wtf/ListHashSetTest.cpp
index 3ec993f5..20d8827e 100644
--- a/third_party/WebKit/Source/wtf/ListHashSetTest.cpp
+++ b/third_party/WebKit/Source/wtf/ListHashSetTest.cpp
@@ -30,14 +30,21 @@
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefCounted.h"
 #include "wtf/RefPtr.h"
+#include <type_traits>
 
 namespace WTF {
 
 namespace {
 
 template <typename Set>
-void removeFirstHelper()
+class ListOrLinkedHashSetTest : public ::testing::Test { };
+
+using SetTypes = ::testing::Types<ListHashSet<int>, ListHashSet<int, 1>, LinkedHashSet<int>>;
+TYPED_TEST_CASE(ListOrLinkedHashSetTest, SetTypes);
+
+TYPED_TEST(ListOrLinkedHashSetTest, RemoveFirst)
 {
+    using Set = TypeParam;
     Set list;
     list.add(-1);
     list.add(0);
@@ -64,20 +71,9 @@
     EXPECT_TRUE(list.isEmpty());
 }
 
-TEST(ListHashSetTest, RemoveFirst)
+TYPED_TEST(ListOrLinkedHashSetTest, AppendOrMoveToLastNewItems)
 {
-    removeFirstHelper<ListHashSet<int>>();
-    removeFirstHelper<ListHashSet<int, 1>>();
-}
-
-TEST(LinkedHashSetTest, RemoveFirst)
-{
-    removeFirstHelper<LinkedHashSet<int>>();
-}
-
-template <typename Set>
-void appendOrMoveToLastNewItems()
-{
+    using Set = TypeParam;
     Set list;
     typename Set::AddResult result = list.appendOrMoveToLast(1);
     EXPECT_TRUE(result.isNewEntry);
@@ -98,20 +94,9 @@
     ++iterator;
 }
 
-TEST(ListHashSetTest, AppendOrMoveToLastNewItems)
+TYPED_TEST(ListOrLinkedHashSetTest, AppendOrMoveToLastWithDuplicates)
 {
-    appendOrMoveToLastNewItems<ListHashSet<int>>();
-    appendOrMoveToLastNewItems<ListHashSet<int, 1>>();
-}
-
-TEST(LinkedHashSetTest, AppendOrMoveToLastNewItems)
-{
-    appendOrMoveToLastNewItems<LinkedHashSet<int>>();
-}
-
-template <typename Set>
-void appendOrMoveToLastWithDuplicates()
-{
+    using Set = TypeParam;
     Set list;
 
     // Add a single element twice.
@@ -149,20 +134,9 @@
     ++iterator;
 }
 
-TEST(ListHashSetTest, AppendOrMoveToLastWithDuplicates)
+TYPED_TEST(ListOrLinkedHashSetTest, PrependOrMoveToFirstNewItems)
 {
-    appendOrMoveToLastWithDuplicates<ListHashSet<int>>();
-    appendOrMoveToLastWithDuplicates<ListHashSet<int, 1>>();
-}
-
-TEST(LinkedHashSetTest, AppendOrMoveToLastWithDuplicates)
-{
-    appendOrMoveToLastWithDuplicates<LinkedHashSet<int>>();
-}
-
-template <typename Set>
-void prependOrMoveToFirstNewItems()
-{
+    using Set = TypeParam;
     Set list;
     typename Set::AddResult result = list.prependOrMoveToFirst(1);
     EXPECT_TRUE(result.isNewEntry);
@@ -183,20 +157,9 @@
     ++iterator;
 }
 
-TEST(ListHashSetTest, PrependOrMoveToFirstNewItems)
+TYPED_TEST(ListOrLinkedHashSetTest, PrependOrMoveToLastWithDuplicates)
 {
-    prependOrMoveToFirstNewItems<ListHashSet<int>>();
-    prependOrMoveToFirstNewItems<ListHashSet<int, 1>>();
-}
-
-TEST(LinkedHashSetTest, PrependOrMoveToFirstNewItems)
-{
-    prependOrMoveToFirstNewItems<LinkedHashSet<int>>();
-}
-
-template <typename Set>
-void prependOrMoveToLastWithDuplicates()
-{
+    using Set = TypeParam;
     Set list;
 
     // Add a single element twice.
@@ -234,80 +197,9 @@
     ++iterator;
 }
 
-TEST(ListHashSetTest, PrependOrMoveToLastWithDuplicates)
+TYPED_TEST(ListOrLinkedHashSetTest, Find)
 {
-    prependOrMoveToLastWithDuplicates<ListHashSet<int>>();
-    prependOrMoveToLastWithDuplicates<ListHashSet<int, 1>>();
-}
-
-TEST(LinkedHashSetTest, PrependOrMoveToLastWithDuplicates)
-{
-    prependOrMoveToLastWithDuplicates<LinkedHashSet<int>>();
-}
-
-class DummyRefCounted : public RefCounted<DummyRefCounted> {
-public:
-    DummyRefCounted(bool& isDeleted) : m_isDeleted(isDeleted) { m_isDeleted = false; }
-    ~DummyRefCounted() { m_isDeleted = true; }
-    void ref()
-    {
-        WTF::RefCounted<DummyRefCounted>::ref();
-        ++m_refInvokesCount;
-    }
-
-    static int m_refInvokesCount;
-
-private:
-    bool& m_isDeleted;
-};
-
-int DummyRefCounted::m_refInvokesCount = 0;
-
-template <typename Set>
-void withRefPtr()
-{
-    bool isDeleted = false;
-    DummyRefCounted::m_refInvokesCount = 0;
-    RefPtr<DummyRefCounted> ptr = adoptRef(new DummyRefCounted(isDeleted));
-    EXPECT_EQ(0, DummyRefCounted::m_refInvokesCount);
-
-    Set set;
-    set.add(ptr);
-    // Referenced only once (to store a copy in the container).
-    EXPECT_EQ(1, DummyRefCounted::m_refInvokesCount);
-    EXPECT_EQ(ptr, set.first());
-    EXPECT_EQ(1, DummyRefCounted::m_refInvokesCount);
-
-    DummyRefCounted* rawPtr = ptr.get();
-
-    EXPECT_TRUE(set.contains(ptr));
-    EXPECT_TRUE(set.contains(rawPtr));
-    EXPECT_EQ(1, DummyRefCounted::m_refInvokesCount);
-
-    ptr.clear();
-    EXPECT_FALSE(isDeleted);
-    EXPECT_EQ(1, DummyRefCounted::m_refInvokesCount);
-
-    set.remove(rawPtr);
-    EXPECT_TRUE(isDeleted);
-
-    EXPECT_EQ(1, DummyRefCounted::m_refInvokesCount);
-}
-
-TEST(ListHashSetTest, WithRefPtr)
-{
-    withRefPtr<ListHashSet<RefPtr<DummyRefCounted>>>();
-    withRefPtr<ListHashSet<RefPtr<DummyRefCounted>, 1>>();
-}
-
-TEST(LinkedHashSetTest, WithRefPtr)
-{
-    withRefPtr<LinkedHashSet<RefPtr<DummyRefCounted>>>();
-}
-
-template <typename Set, typename SetRef, typename Iterator>
-void findHelper()
-{
+    using Set = TypeParam;
     Set set;
     set.add(-1);
     set.add(0);
@@ -315,33 +207,32 @@
     set.add(2);
     set.add(3);
 
-    SetRef ref = set;
-    Iterator it = ref.find(2);
-    EXPECT_EQ(2, *it);
-    ++it;
-    EXPECT_EQ(3, *it);
-    --it;
-    --it;
-    EXPECT_EQ(1, *it);
+    {
+        const Set& ref = set;
+        typename Set::const_iterator it = ref.find(2);
+        EXPECT_EQ(2, *it);
+        ++it;
+        EXPECT_EQ(3, *it);
+        --it;
+        --it;
+        EXPECT_EQ(1, *it);
+    }
+    {
+        Set& ref = set;
+        typename Set::iterator it = ref.find(2);
+        EXPECT_EQ(2, *it);
+        ++it;
+        EXPECT_EQ(3, *it);
+        --it;
+        --it;
+        EXPECT_EQ(1, *it);
+    }
 }
 
-TEST(ListHashSetTest, Find)
+TYPED_TEST(ListOrLinkedHashSetTest, InsertBefore)
 {
-    findHelper<ListHashSet<int>, const ListHashSet<int>&, ListHashSet<int>::const_iterator>();
-    findHelper<ListHashSet<int>, ListHashSet<int>&, ListHashSet<int>::iterator>();
-    findHelper<ListHashSet<int, 1>, const ListHashSet<int, 1>&, ListHashSet<int, 1>::const_iterator>();
-    findHelper<ListHashSet<int, 1>, ListHashSet<int, 1>&, ListHashSet<int, 1>::iterator>();
-}
-
-TEST(LinkedHashSetTest, Find)
-{
-    findHelper<LinkedHashSet<int>, const LinkedHashSet<int>&, LinkedHashSet<int>::const_iterator>();
-    findHelper<LinkedHashSet<int>, LinkedHashSet<int>&, LinkedHashSet<int>::iterator>();
-}
-
-template <typename Set>
-void insertBeforeHelper(bool canModifyWhileIterating)
-{
+    using Set = TypeParam;
+    bool canModifyWhileIterating = !std::is_same<Set, LinkedHashSet<int>>::value;
     Set set;
     set.add(-1);
     set.add(0);
@@ -385,20 +276,10 @@
     EXPECT_EQ(7u, set.size());
 }
 
-TEST(ListHashSetTest, InsertBefore)
+TYPED_TEST(ListOrLinkedHashSetTest, AddReturnIterator)
 {
-    insertBeforeHelper<ListHashSet<int>>(true);
-    insertBeforeHelper<ListHashSet<int, 1>>(true);
-}
-
-TEST(LinkedHashSetTest, InsertBefore)
-{
-    insertBeforeHelper<LinkedHashSet<int>>(false);
-}
-
-template <typename Set>
-void addReturnIterator(bool canModifyWhileIterating)
-{
+    using Set = TypeParam;
+    bool canModifyWhileIterating = !std::is_same<Set, LinkedHashSet<int>>::value;
     Set set;
     set.add(-1);
     set.add(0);
@@ -443,20 +324,116 @@
     EXPECT_EQ(4, set.last());
 }
 
-TEST(ListHashSetTest, AddReturnIterator)
+TYPED_TEST(ListOrLinkedHashSetTest, Swap)
 {
-    addReturnIterator<ListHashSet<int>>(true);
-    addReturnIterator<ListHashSet<int, 1>>(true);
+    using Set = TypeParam;
+    int num = 10;
+    Set set0;
+    Set set1;
+    Set set2;
+    for (int i = 0; i < num; ++i) {
+        set1.add(i + 1);
+        set2.add(num - i);
+    }
+
+    typename Set::iterator it1 = set1.begin();
+    typename Set::iterator it2 = set2.begin();
+    for (int i = 0; i < num; ++i, ++it1, ++it2) {
+        EXPECT_EQ(*it1, i + 1);
+        EXPECT_EQ(*it2, num - i);
+    }
+    EXPECT_EQ(set0.begin(), set0.end());
+    EXPECT_EQ(it1, set1.end());
+    EXPECT_EQ(it2, set2.end());
+
+    // Shift sets: 2->1, 1->0, 0->2
+    set1.swap(set2); // Swap with non-empty sets.
+    set0.swap(set2); // Swap with an empty set.
+
+    it1 = set0.begin();
+    it2 = set1.begin();
+    for (int i = 0; i < num; ++i, ++it1, ++it2) {
+        EXPECT_EQ(*it1, i + 1);
+        EXPECT_EQ(*it2, num - i);
+    }
+    EXPECT_EQ(it1, set0.end());
+    EXPECT_EQ(it2, set1.end());
+    EXPECT_EQ(set2.begin(), set2.end());
+
+    int removedIndex = num >> 1;
+    set0.remove(removedIndex + 1);
+    set1.remove(num - removedIndex);
+
+    it1 = set0.begin();
+    it2 = set1.begin();
+    for (int i = 0; i < num; ++i, ++it1, ++it2) {
+        if (i == removedIndex)
+            ++i;
+        EXPECT_EQ(*it1, i + 1);
+        EXPECT_EQ(*it2, num - i);
+    }
+    EXPECT_EQ(it1, set0.end());
+    EXPECT_EQ(it2, set1.end());
 }
 
-TEST(LinkedHashSetTest, AddReturnIterator)
-{
-    addReturnIterator<LinkedHashSet<int>>(false);
-}
+class DummyRefCounted : public RefCounted<DummyRefCounted> {
+public:
+    DummyRefCounted(bool& isDeleted) : m_isDeleted(isDeleted) { m_isDeleted = false; }
+    ~DummyRefCounted() { m_isDeleted = true; }
+    void ref()
+    {
+        WTF::RefCounted<DummyRefCounted>::ref();
+        ++m_refInvokesCount;
+    }
+
+    static int m_refInvokesCount;
+
+private:
+    bool& m_isDeleted;
+};
+
+int DummyRefCounted::m_refInvokesCount = 0;
 
 template <typename Set>
-void excerciseValuePeekInType()
+class ListOrLinkedHashSetRefPtrTest : public ::testing::Test { };
+
+using RefPtrSetTypes = ::testing::Types<ListHashSet<RefPtr<DummyRefCounted>>, ListHashSet<RefPtr<DummyRefCounted>, 1>, LinkedHashSet<RefPtr<DummyRefCounted>>>;
+TYPED_TEST_CASE(ListOrLinkedHashSetRefPtrTest, RefPtrSetTypes);
+
+TYPED_TEST(ListOrLinkedHashSetRefPtrTest, WithRefPtr)
 {
+    using Set = TypeParam;
+    bool isDeleted = false;
+    DummyRefCounted::m_refInvokesCount = 0;
+    RefPtr<DummyRefCounted> ptr = adoptRef(new DummyRefCounted(isDeleted));
+    EXPECT_EQ(0, DummyRefCounted::m_refInvokesCount);
+
+    Set set;
+    set.add(ptr);
+    // Referenced only once (to store a copy in the container).
+    EXPECT_EQ(1, DummyRefCounted::m_refInvokesCount);
+    EXPECT_EQ(ptr, set.first());
+    EXPECT_EQ(1, DummyRefCounted::m_refInvokesCount);
+
+    DummyRefCounted* rawPtr = ptr.get();
+
+    EXPECT_TRUE(set.contains(ptr));
+    EXPECT_TRUE(set.contains(rawPtr));
+    EXPECT_EQ(1, DummyRefCounted::m_refInvokesCount);
+
+    ptr.clear();
+    EXPECT_FALSE(isDeleted);
+    EXPECT_EQ(1, DummyRefCounted::m_refInvokesCount);
+
+    set.remove(rawPtr);
+    EXPECT_TRUE(isDeleted);
+
+    EXPECT_EQ(1, DummyRefCounted::m_refInvokesCount);
+}
+
+TYPED_TEST(ListOrLinkedHashSetRefPtrTest, ExerciseValuePeekInType)
+{
+    using Set = TypeParam;
     Set set;
     bool isDeleted = false;
     bool isDeleted2 = false;
@@ -491,17 +468,6 @@
     EXPECT_EQ(0u, set.size());
 }
 
-TEST(ListHashSetTest, ExcerciseValuePeekInType)
-{
-    excerciseValuePeekInType<ListHashSet<RefPtr<DummyRefCounted>>>();
-    excerciseValuePeekInType<ListHashSet<RefPtr<DummyRefCounted>, 1>>();
-}
-
-TEST(LinkedHashSetTest, ExcerciseValuePeekInType)
-{
-    excerciseValuePeekInType<LinkedHashSet<RefPtr<DummyRefCounted>>>();
-}
-
 struct Simple {
     Simple(int value) : m_value(value) { };
     int m_value;
@@ -537,8 +503,17 @@
 };
 
 template <typename Set>
-void translatorTest()
+class ListOrLinkedHashSetTranslatorTest : public ::testing::Test { };
+
+using TranslatorSetTypes = ::testing::Types<
+    ListHashSet<Complicated, 256, ComplicatedHashFunctions>,
+    ListHashSet<Complicated, 1, ComplicatedHashFunctions>,
+    LinkedHashSet<Complicated, ComplicatedHashFunctions>>;
+TYPED_TEST_CASE(ListOrLinkedHashSetTranslatorTest, TranslatorSetTypes);
+
+TYPED_TEST(ListOrLinkedHashSetTranslatorTest, ComplexityTranslator)
 {
+    using Set = TypeParam;
     Set set;
     set.add(Complicated(42));
     int baseLine = Complicated::s_objectsConstructed;
@@ -562,17 +537,6 @@
     EXPECT_EQ(baseLine, Complicated::s_objectsConstructed);
 }
 
-TEST(ListHashSetTest, ComplexityTranslator)
-{
-    translatorTest<ListHashSet<Complicated, 256, ComplicatedHashFunctions>>();
-    translatorTest<ListHashSet<Complicated, 1, ComplicatedHashFunctions>>();
-}
-
-TEST(LinkedHashSetTest, ComplexityTranslator)
-{
-    translatorTest<LinkedHashSet<Complicated, ComplicatedHashFunctions>>();
-}
-
 struct Dummy {
     Dummy(bool& deleted) : deleted(deleted) { }
 
@@ -657,68 +621,6 @@
     EXPECT_EQ(ptr2, ownPtr2);
 }
 
-template <typename Set>
-void swapTestHelper()
-{
-    int num = 10;
-    Set set0;
-    Set set1;
-    Set set2;
-    for (int i = 0; i < num; ++i) {
-        set1.add(i + 1);
-        set2.add(num - i);
-    }
-
-    typename Set::iterator it1 = set1.begin();
-    typename Set::iterator it2 = set2.begin();
-    for (int i = 0; i < num; ++i, ++it1, ++it2) {
-        EXPECT_EQ(*it1, i + 1);
-        EXPECT_EQ(*it2, num - i);
-    }
-    EXPECT_EQ(set0.begin(), set0.end());
-    EXPECT_EQ(it1, set1.end());
-    EXPECT_EQ(it2, set2.end());
-
-    // Shift sets: 2->1, 1->0, 0->2
-    set1.swap(set2); // Swap with non-empty sets.
-    set0.swap(set2); // Swap with an empty set.
-
-    it1 = set0.begin();
-    it2 = set1.begin();
-    for (int i = 0; i < num; ++i, ++it1, ++it2) {
-        EXPECT_EQ(*it1, i + 1);
-        EXPECT_EQ(*it2, num - i);
-    }
-    EXPECT_EQ(it1, set0.end());
-    EXPECT_EQ(it2, set1.end());
-    EXPECT_EQ(set2.begin(), set2.end());
-
-    int removedIndex = num >> 1;
-    set0.remove(removedIndex + 1);
-    set1.remove(num - removedIndex);
-
-    it1 = set0.begin();
-    it2 = set1.begin();
-    for (int i = 0; i < num; ++i, ++it1, ++it2) {
-        if (i == removedIndex)
-            ++i;
-        EXPECT_EQ(*it1, i + 1);
-        EXPECT_EQ(*it2, num - i);
-    }
-    EXPECT_EQ(it1, set0.end());
-    EXPECT_EQ(it2, set1.end());
-}
-
-TEST(ListHashSetTest, Swap)
-{
-    swapTestHelper<ListHashSet<int>>();
-}
-
-TEST(LinkedHashSetTest, Swap)
-{
-    swapTestHelper<LinkedHashSet<int>>();
-}
-
 class CountCopy final {
 public:
     static int* const kDeletedValue;
@@ -764,20 +666,26 @@
 namespace {
 
 template <typename Set>
-int moveConstructorCopyCount()
+class ListOrLinkedHashSetCountCopyTest : public ::testing::Test { };
+
+using CountCopySetTypes = ::testing::Types<ListHashSet<CountCopy>, ListHashSet<CountCopy, 1>, LinkedHashSet<CountCopy>>;
+TYPED_TEST_CASE(ListOrLinkedHashSetCountCopyTest, CountCopySetTypes);
+
+TYPED_TEST(ListOrLinkedHashSetCountCopyTest, MoveConstructionShouldNotMakeCopy)
 {
+    using Set = TypeParam;
     Set set;
     int counter = 0;
     set.add(CountCopy(&counter));
 
     counter = 0;
     Set other(std::move(set));
-    return counter;
+    EXPECT_EQ(0, counter);
 }
 
-template <typename Set>
-int moveAssignmentCopyCount()
+TYPED_TEST(ListOrLinkedHashSetCountCopyTest, MoveAssignmentShouldNotMakeACopy)
 {
+    using Set = TypeParam;
     Set set;
     int counter = 0;
     set.add(CountCopy(&counter));
@@ -785,19 +693,7 @@
     Set other(set);
     counter = 0;
     set = std::move(other);
-    return counter;
-}
-
-TEST(ListHashSetTest, MoveShouldNotMakeCopy)
-{
-    EXPECT_EQ(0, moveConstructorCopyCount<ListHashSet<CountCopy>>());
-    EXPECT_EQ(0, moveAssignmentCopyCount<ListHashSet<CountCopy>>());
-}
-
-TEST(LinkedHashSetTest, MoveAssignmentShouldNotMakeACopy)
-{
-    EXPECT_EQ(0, moveConstructorCopyCount<LinkedHashSet<CountCopy>>());
-    EXPECT_EQ(0, moveAssignmentCopyCount<LinkedHashSet<CountCopy>>());
+    EXPECT_EQ(0, counter);
 }
 
 } // anonymous namespace
diff --git a/third_party/WebKit/Source/wtf/Partitions.cpp b/third_party/WebKit/Source/wtf/Partitions.cpp
index f86bf23..bd3f40d 100644
--- a/third_party/WebKit/Source/wtf/Partitions.cpp
+++ b/third_party/WebKit/Source/wtf/Partitions.cpp
@@ -189,7 +189,7 @@
 {
     size_t signature = 16 * 1024 * 1024 - 1;
     base::debug::Alias(&signature);
-    IMMEDIATE_CRASH();
+    FATAL("ParitionAlloc: out of memory with < 16M usage (error:%u)", getAllocPageErrorCode());
 }
 
 void Partitions::handleOutOfMemory()
diff --git a/third_party/WebKit/Source/wtf/text/AtomicString.cpp b/third_party/WebKit/Source/wtf/text/AtomicString.cpp
index cad9b6d2..120a153 100644
--- a/third_party/WebKit/Source/wtf/text/AtomicString.cpp
+++ b/third_party/WebKit/Source/wtf/text/AtomicString.cpp
@@ -118,7 +118,7 @@
 template<typename T, typename HashTranslator>
 static inline PassRefPtr<StringImpl> addToStringTable(const T& value)
 {
-    HashSet<StringImpl*>::AddResult addResult = atomicStrings().add<HashTranslator>(value);
+    HashSet<StringImpl*>::AddResult addResult = atomicStrings().addWithTranslator<HashTranslator>(value);
 
     // If the string is newly-translated, then we need to adopt it.
     // The boolean in the pair tells us if that is so.
diff --git a/third_party/WebKit/Source/wtf/text/StringHash.h b/third_party/WebKit/Source/wtf/text/StringHash.h
index 5f4d843d..025f03c 100644
--- a/third_party/WebKit/Source/wtf/text/StringHash.h
+++ b/third_party/WebKit/Source/wtf/text/StringHash.h
@@ -91,6 +91,11 @@
         return CaseFoldingHash::hash(reinterpret_cast<const LChar*>(data), length);
     }
 
+    static inline unsigned hash(const char* data)
+    {
+        return CaseFoldingHash::hash(reinterpret_cast<const LChar*>(data), strlen(data));
+    }
+
     static inline bool equal(const StringImpl* a, const StringImpl* b)
     {
         return equalIgnoringCaseNonNull(a, b);
diff --git a/third_party/WebKit/public/platform/WebGraphicsContext3D.h b/third_party/WebKit/public/platform/WebGraphicsContext3D.h
index cd8a5d46..89ad941 100644
--- a/third_party/WebKit/public/platform/WebGraphicsContext3D.h
+++ b/third_party/WebKit/public/platform/WebGraphicsContext3D.h
@@ -35,6 +35,12 @@
 #include "WebNonCopyable.h"
 #include "WebString.h"
 
+namespace gpu {
+namespace gles2 {
+class GLES2Interface;
+}
+}
+
 struct GrGLInterface;
 
 namespace blink {
@@ -169,8 +175,6 @@
     // getError in the order they were added.
     virtual void synthesizeGLError(WGC3Denum) = 0;
 
-    virtual bool isContextLost() = 0;
-
     // GL_CHROMIUM_map_sub
     virtual void* mapBufferSubDataCHROMIUM(WGC3Denum target, WGC3Dintptr offset, WGC3Dsizeiptr size, WGC3Denum access) = 0;
     virtual void unmapBufferSubDataCHROMIUM(const void*) = 0;
@@ -550,6 +554,9 @@
     virtual void vertexAttribI4uiv(WGC3Duint index, const WGC3Duint *v) { }
     virtual void vertexAttribIPointer(WGC3Duint index, WGC3Dint size, WGC3Denum type, WGC3Dsizei stride, WGC3Dintptr pointer) { }
     virtual void waitSync(WGC3Dsync sync, WGC3Dbitfield flags, WGC3Duint64 timeout) { }
+
+    // Prefer getting a GLES2Interface off WebGraphicsContext3DProvider if possible, and avoid using WebGraphicsContext3D at all.
+    virtual gpu::gles2::GLES2Interface* getGLES2Interface() = 0;
 };
 
 } // namespace blink
diff --git a/third_party/WebKit/public/platform/WebGraphicsContext3DProvider.h b/third_party/WebKit/public/platform/WebGraphicsContext3DProvider.h
index c71432d..709c1d25 100644
--- a/third_party/WebKit/public/platform/WebGraphicsContext3DProvider.h
+++ b/third_party/WebKit/public/platform/WebGraphicsContext3DProvider.h
@@ -35,6 +35,12 @@
 
 class GrContext;
 
+namespace gpu {
+namespace gles2 {
+class GLES2Interface;
+}
+}
+
 namespace blink {
 
 class WebGraphicsContext3D;
@@ -44,6 +50,7 @@
     virtual ~WebGraphicsContext3DProvider() { }
 
     virtual WebGraphicsContext3D* context3d() = 0;
+    virtual gpu::gles2::GLES2Interface* contextGL() = 0;
     virtual GrContext* grContext() = 0;
 };
 
diff --git a/third_party/WebKit/public/web/WebWorkerContentSettingsClientProxy.h b/third_party/WebKit/public/web/WebWorkerContentSettingsClientProxy.h
index 952263052..dfb44275 100644
--- a/third_party/WebKit/public/web/WebWorkerContentSettingsClientProxy.h
+++ b/third_party/WebKit/public/web/WebWorkerContentSettingsClientProxy.h
@@ -18,12 +18,6 @@
 public:
     virtual ~WebWorkerContentSettingsClientProxy() { }
 
-    // Deprecated: This function should be removed.
-    virtual bool allowDatabase(const WebString& name, const WebString& displayName, unsigned long estimatedSize)
-    {
-        return true;
-    }
-
     virtual bool requestFileSystemAccessSync()
     {
         return true;
diff --git a/third_party/closure_compiler/externs/compiled_resources2.gyp b/third_party/closure_compiler/externs/compiled_resources2.gyp
index 9efbcea..947de7d 100644
--- a/third_party/closure_compiler/externs/compiled_resources2.gyp
+++ b/third_party/closure_compiler/externs/compiled_resources2.gyp
@@ -84,5 +84,9 @@
       'target_name': 'users_private',
       'includes': ['../include_js.gypi'],
     },
+    {
+      'target_name': 'web_animations',
+      'includes': ['../include_js.gypi'],
+    },
   ],
 }
diff --git a/third_party/closure_compiler/externs/web_animations.js b/third_party/closure_compiler/externs/web_animations.js
new file mode 100644
index 0000000..9eaa712
--- /dev/null
+++ b/third_party/closure_compiler/externs/web_animations.js
@@ -0,0 +1,142 @@
+// 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.
+
+/**
+ * @fileoverview Minimal Closure externs for Web Animations.
+ * "Minimal" because the web-animations spec is in flux, Chromium's support is
+ * changing, and the intended consumer (MD Settings) is actually using the
+ * web-animations-js polyfill for the time being.
+ * @see https://w3c.github.io/web-animations/#programming-interface
+ */
+
+/**
+ * @enum {number}
+ * @see https://w3c.github.io/web-animations/#enumdef-fillmode
+ */
+var FillMode = {
+  'none': 0,
+  'forwards': 1,
+  'backwards': 2,
+  'both': 3,
+  'auto': 4
+};
+
+/**
+ * @enum {number}
+ * @see https://w3c.github.io/web-animations/#enumdef-playbackdirection
+ */
+var PlaybackDirection = {
+  'normal': 0,
+  'reverse': 1,
+  'alternate': 2,
+  'alternate-reverse': 3
+};
+
+/**
+ * @constructor
+ * @param {!Event} event
+ */
+var EventHandlerNonNull = function(event) {};
+
+/** @typedef {?EventHandlerNonNull} */
+var EventHandler;
+
+/**
+ * @constructor
+ * @see https://w3c.github.io/web-animations/#dictdef-keyframeanimationoptions
+ */
+var KeyframeAnimationOptions = function() {};
+
+/**
+ * @constructor
+ * @see https://w3c.github.io/web-animations/#dictdef-keyframeeffectoptions
+ */
+var KeyframeEffectOptions = function() {};
+
+/** @type {number} */
+KeyframeEffectOptions.prototype.delay;
+
+/** @type {number} */
+KeyframeEffectOptions.prototype.endDelay;
+
+/** @type {!FillMode} */
+KeyframeEffectOptions.prototype.fill;
+
+/** @type {number} */
+KeyframeEffectOptions.prototype.iterationStart;
+
+/** @type {number} */
+KeyframeEffectOptions.prototype.iterations;
+
+/** @type {number|string} */
+KeyframeEffectOptions.prototype.duration;
+
+/** @type {number} */
+KeyframeEffectOptions.prototype.playbackRate;
+
+/** @type {!PlaybackDirection} */
+KeyframeEffectOptions.prototype.direction;
+
+/** @type {string} */
+KeyframeEffectOptions.prototype.easing;
+
+/** @type {string} */
+KeyframeEffectOptions.prototype.id;
+
+/**
+ * @interface
+ * @extends {EventTarget}
+ * @see https://w3c.github.io/web-animations/#animation
+ */
+var Animation = function() {};
+
+/** @type {string} */
+Animation.prototype.id;
+
+/** @type {?number} */
+Animation.prototype.startTime;
+
+/** @type {?number} */
+Animation.prototype.currentTime;
+
+/** @type {number} */
+Animation.prototype.playbackRate;
+
+Animation.prototype.finish = function() {};
+
+Animation.prototype.play = function() {};
+
+Animation.prototype.pause = function() {};
+
+Animation.prototype.reverse = function() {};
+
+Animation.prototype.cancel = function() {};
+
+/**
+ * @param {boolean=} opt_useCapture
+ * @override
+ */
+Animation.prototype.addEventListener = function(
+    type, listener, opt_useCapture) {};
+
+/** @type {EventHandler} */
+Animation.prototype.onfinish;
+
+/** @type {EventHandler} */
+Animation.prototype.oncancel;
+
+/**
+ * @interface
+ * @see https://w3c.github.io/web-animations/#animatable
+ */
+var Animatable = function() {};
+
+Animatable.prototype = /** @lends {Element.prototype} */({
+  /**
+   * @param {?Array<Object>|Object} effect
+   * @param {number|!KeyframeEffectOptions=} opt_timing
+   * @return {!Animation}
+   */
+  animate: function(effect, opt_timing) {},
+});
diff --git a/third_party/libjingle/BUILD.gn b/third_party/libjingle/BUILD.gn
index 962ec91..671a0bfb 100644
--- a/third_party/libjingle/BUILD.gn
+++ b/third_party/libjingle/BUILD.gn
@@ -343,10 +343,6 @@
       "../webrtc/api/webrtcsessiondescriptionfactory.cc",
       "../webrtc/api/webrtcsessiondescriptionfactory.h",
       "../webrtc/media/base/audiorenderer.h",
-      "../webrtc/media/base/capturemanager.cc",
-      "../webrtc/media/base/capturemanager.h",
-      "../webrtc/media/base/capturerenderadapter.cc",
-      "../webrtc/media/base/capturerenderadapter.h",
       "../webrtc/media/base/codec.cc",
       "../webrtc/media/base/codec.h",
       "../webrtc/media/base/cryptoparams.h",
@@ -378,6 +374,8 @@
       "../webrtc/media/base/videoframe.h",
       "../webrtc/media/base/videoframefactory.cc",
       "../webrtc/media/base/videoframefactory.h",
+      "../webrtc/media/base/videosourcebase.cc",
+      "../webrtc/media/base/videosourcebase.h",
       "../webrtc/media/engine/webrtccommon.h",
       "../webrtc/media/engine/webrtcvideoframe.cc",
       "../webrtc/media/engine/webrtcvideoframe.h",
diff --git a/third_party/libjingle/libjingle.gyp b/third_party/libjingle/libjingle.gyp
index 586368c..3c3ecfba 100644
--- a/third_party/libjingle/libjingle.gyp
+++ b/third_party/libjingle/libjingle.gyp
@@ -308,10 +308,6 @@
             '<(DEPTH)/third_party/webrtc/api/webrtcsessiondescriptionfactory.cc',
             '<(DEPTH)/third_party/webrtc/api/webrtcsessiondescriptionfactory.h',
             '<(DEPTH)/third_party/webrtc/media/base/audiorenderer.h',
-            '<(DEPTH)/third_party/webrtc/media/base/capturemanager.cc',
-            '<(DEPTH)/third_party/webrtc/media/base/capturemanager.h',
-            '<(DEPTH)/third_party/webrtc/media/base/capturerenderadapter.cc',
-            '<(DEPTH)/third_party/webrtc/media/base/capturerenderadapter.h',
             '<(DEPTH)/third_party/webrtc/media/base/codec.cc',
             '<(DEPTH)/third_party/webrtc/media/base/codec.h',
             '<(DEPTH)/third_party/webrtc/media/base/cryptoparams.h',
@@ -343,6 +339,8 @@
             '<(DEPTH)/third_party/webrtc/media/base/videoframe.h',
             '<(DEPTH)/third_party/webrtc/media/base/videoframefactory.cc',
             '<(DEPTH)/third_party/webrtc/media/base/videoframefactory.h',
+            '<(DEPTH)/third_party/webrtc/media/base/videosourcebase.cc',
+            '<(DEPTH)/third_party/webrtc/media/base/videosourcebase.h',
             '<(DEPTH)/third_party/webrtc/media/engine/webrtccommon.h',
             '<(DEPTH)/third_party/webrtc/media/engine/webrtcvideoframe.cc',
             '<(DEPTH)/third_party/webrtc/media/engine/webrtcvideoframe.h',
diff --git a/third_party/wayland-protocols/src/unstable/scaler/scaler.xml b/third_party/wayland-protocols/src/unstable/scaler/scaler.xml
deleted file mode 100644
index 0e482a6..0000000
--- a/third_party/wayland-protocols/src/unstable/scaler/scaler.xml
+++ /dev/null
@@ -1,208 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<protocol name="scaler">
-
-  <copyright>
-    Copyright © 2013-2014 Collabora, Ltd.
-
-    Permission is hereby granted, free of charge, to any person obtaining a
-    copy of this software and associated documentation files (the "Software"),
-    to deal in the Software without restriction, including without limitation
-    the rights to use, copy, modify, merge, publish, distribute, sublicense,
-    and/or sell copies of the Software, and to permit persons to whom the
-    Software is furnished to do so, subject to the following conditions:
-
-    The above copyright notice and this permission notice (including the next
-    paragraph) shall be included in all copies or substantial portions of the
-    Software.
-
-    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
-    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-    DEALINGS IN THE SOFTWARE.
-  </copyright>
-
-  <interface name="wl_scaler" version="2">
-    <description summary="surface cropping and scaling">
-      The global interface exposing surface cropping and scaling
-      capabilities is used to instantiate an interface extension for a
-      wl_surface object. This extended interface will then allow
-      cropping and scaling the surface contents, effectively
-      disconnecting the direct relationship between the buffer and the
-      surface size.
-    </description>
-
-    <request name="destroy" type="destructor">
-      <description summary="unbind from the cropping and scaling interface">
-	Informs the server that the client will not be using this
-	protocol object anymore. This does not affect any other objects,
-	wl_viewport objects included.
-      </description>
-    </request>
-
-    <enum name="error">
-      <entry name="viewport_exists" value="0"
-             summary="the surface already has a viewport object associated"/>
-    </enum>
-
-    <request name="get_viewport">
-      <description summary="extend surface interface for crop and scale">
-	Instantiate an interface extension for the given wl_surface to
-	crop and scale its content. If the given wl_surface already has
-	a wl_viewport object associated, the viewport_exists
-	protocol error is raised.
-      </description>
-
-      <arg name="id" type="new_id" interface="wl_viewport"
-           summary="the new viewport interface id"/>
-      <arg name="surface" type="object" interface="wl_surface"
-           summary="the surface"/>
-    </request>
-  </interface>
-
-  <interface name="wl_viewport" version="2">
-    <description summary="crop and scale interface to a wl_surface">
-      An additional interface to a wl_surface object, which allows the
-      client to specify the cropping and scaling of the surface
-      contents.
-
-      This interface allows to define the source rectangle (src_x,
-      src_y, src_width, src_height) from where to take the wl_buffer
-      contents, and scale that to destination size (dst_width,
-      dst_height). This state is double-buffered, and is applied on the
-      next wl_surface.commit.
-
-      The two parts of crop and scale state are independent: the source
-      rectangle, and the destination size. Initially both are unset, that
-      is, no scaling is applied. The whole of the current wl_buffer is
-      used as the source, and the surface size is as defined in
-      wl_surface.attach.
-
-      If the destination size is set, it causes the surface size to become
-      dst_width, dst_height. The source (rectangle) is scaled to exactly
-      this size. This overrides whatever the attached wl_buffer size is,
-      unless the wl_buffer is NULL. If the wl_buffer is NULL, the surface
-      has no content and therefore no size. Otherwise, the size is always
-      at least 1x1 in surface coordinates.
-
-      If the source rectangle is set, it defines what area of the
-      wl_buffer is taken as the source. If the source rectangle is set and
-      the destination size is not set, the surface size becomes the source
-      rectangle size rounded up to the nearest integer. If the source size
-      is already exactly integers, this results in cropping without scaling.
-
-      The coordinate transformations from buffer pixel coordinates up to
-      the surface-local coordinates happen in the following order:
-        1. buffer_transform (wl_surface.set_buffer_transform)
-        2. buffer_scale (wl_surface.set_buffer_scale)
-        3. crop and scale (wl_viewport.set*)
-      This means, that the source rectangle coordinates of crop and scale
-      are given in the coordinates after the buffer transform and scale,
-      i.e. in the coordinates that would be the surface-local coordinates
-      if the crop and scale was not applied.
-
-      If the source rectangle is partially or completely outside of the
-      wl_buffer, then the surface contents are undefined (not void), and
-      the surface size is still dst_width, dst_height.
-
-      The x, y arguments of wl_surface.attach are applied as normal to
-      the surface. They indicate how many pixels to remove from the
-      surface size from the left and the top. In other words, they are
-      still in the surface-local coordinate system, just like dst_width
-      and dst_height are.
-
-      If the wl_surface associated with the wl_viewport is destroyed,
-      the wl_viewport object becomes inert.
-
-      If the wl_viewport object is destroyed, the crop and scale
-      state is removed from the wl_surface. The change will be applied
-      on the next wl_surface.commit.
-    </description>
-
-    <request name="destroy" type="destructor">
-      <description summary="remove scaling and cropping from the surface">
-	The associated wl_surface's crop and scale state is removed.
-	The change is applied on the next wl_surface.commit.
-      </description>
-    </request>
-
-    <enum name="error">
-      <entry name="bad_value" value="0"
-             summary="negative or zero values in width or height"/>
-    </enum>
-
-    <request name="set">
-      <description summary="set the crop and scale state">
-	Set both source rectangle and destination size of the associated
-	wl_surface. See wl_viewport for the description, and relation to
-	the wl_buffer size.
-
-	The bad_value protocol error is raised if src_width or
-	src_height is negative, or if dst_width or dst_height is not
-	positive.
-
-	The crop and scale state is double-buffered state, and will be
-	applied on the next wl_surface.commit.
-
-	Arguments dst_x and dst_y do not exist here, use the x and y
-	arguments to wl_surface.attach. The x, y, dst_width, and dst_height
-	define the surface-local coordinate system irrespective of the
-	attached wl_buffer size.
-      </description>
-
-      <arg name="src_x" type="fixed" summary="source rectangle x"/>
-      <arg name="src_y" type="fixed" summary="source rectangle y"/>
-      <arg name="src_width" type="fixed" summary="source rectangle width"/>
-      <arg name="src_height" type="fixed" summary="source rectangle height"/>
-      <arg name="dst_width" type="int" summary="surface width"/>
-      <arg name="dst_height" type="int" summary="surface height"/>
-    </request>
-
-    <request name="set_source" since="2">
-      <description summary="set the source rectangle for cropping">
-	Set the source rectangle of the associated wl_surface. See
-	wl_viewport for the description, and relation to the wl_buffer
-	size.
-
-	If width is -1.0 and height is -1.0, the source rectangle is unset
-	instead. Any other pair of values for width and height that
-	contains zero or negative values raises the bad_value protocol
-	error.
-
-	The crop and scale state is double-buffered state, and will be
-	applied on the next wl_surface.commit.
-      </description>
-
-      <arg name="x" type="fixed" summary="source rectangle x"/>
-      <arg name="y" type="fixed" summary="source rectangle y"/>
-      <arg name="width" type="fixed" summary="source rectangle width"/>
-      <arg name="height" type="fixed" summary="source rectangle height"/>
-    </request>
-
-    <request name="set_destination" since="2">
-      <description summary="set the surface size for scaling">
-	Set the destination size of the associated wl_surface. See
-	wl_viewport for the description, and relation to the wl_buffer
-	size.
-
-	If width is -1 and height is -1, the destination size is unset
-	instead. Any other pair of values for width and height that
-	contains zero or negative values raises the bad_value protocol
-	error.
-
-	The crop and scale state is double-buffered state, and will be
-	applied on the next wl_surface.commit.
-
-	Arguments x and y do not exist here, use the x and y arguments to
-	wl_surface.attach. The x, y, width, and height define the
-	surface-local coordinate system irrespective of the attached
-	wl_buffer size.
-      </description>
-
-      <arg name="width" type="int" summary="surface width"/>
-      <arg name="height" type="int" summary="surface height"/>
-    </request>
-  </interface>
-</protocol>
diff --git a/tools/mb/mb.py b/tools/mb/mb.py
index c2650ed4..fe46c46 100755
--- a/tools/mb/mb.py
+++ b/tools/mb/mb.py
@@ -29,16 +29,7 @@
 
 def main(args):
   mbw = MetaBuildWrapper()
-  mbw.ParseArgs(args)
-
-  try:
-    ret = mbw.args.func()
-    if ret:
-      mbw.DumpInputFiles()
-    return ret
-  except Exception:
-    mbw.DumpInputFiles()
-    raise
+  return mbw.Main(args)
 
 
 class MetaBuildWrapper(object):
@@ -59,6 +50,21 @@
     self.common_dev_configs = []
     self.unsupported_configs = []
 
+  def Main(self, args):
+    self.ParseArgs(args)
+    try:
+      ret = self.args.func()
+      if ret:
+        self.DumpInputFiles()
+      return ret
+    except KeyboardInterrupt:
+      self.Print('interrupted, exiting', stream=sys.stderr)
+      return 130
+    except Exception as e:
+      self.DumpInputFiles()
+      self.Print(str(e))
+      return 1
+
   def ParseArgs(self, argv):
     def AddCommonOptions(subp):
       subp.add_argument('-b', '--builder',
@@ -326,27 +332,28 @@
       if not mixin in referenced_mixins:
         errs.append('Unreferenced mixin "%s".' % mixin)
 
-    # Check that 'chromium' bots which build public artifacts do not include
-    # the chrome_with_codecs 'mixin'.
-    if not 'chromium' in self.masters:
-      errs.append('Missing "chromium" master. Please update this proprietary '
-                  'codecs check with the name of the master responsible for '
-                  'public build artifacts.')
-    else:
-      for builder in self.masters['chromium']:
-        config = self.masters['chromium'][builder]
-        def RecurseMixins(current_mixin):
-          if current_mixin == 'chrome_with_codecs':
-            errs.append('Public artifact builder "%s" can not contain the '
-                        '"chrome_with_codecs" mixin.' % builder)
-            return
-          if not 'mixins' in self.mixins[current_mixin]:
-            return
-          for mixin in self.mixins[current_mixin]['mixins']:
-            RecurseMixins(mixin)
+    # If we're checking the Chromium config, check that the 'chromium' bots
+    # which build public artifacts do not include the chrome_with_codecs mixin.
+    if self.args.config_file == self.default_config:
+      if 'chromium' in self.masters:
+        for builder in self.masters['chromium']:
+          config = self.masters['chromium'][builder]
+          def RecurseMixins(current_mixin):
+            if current_mixin == 'chrome_with_codecs':
+              errs.append('Public artifact builder "%s" can not contain the '
+                          '"chrome_with_codecs" mixin.' % builder)
+              return
+            if not 'mixins' in self.mixins[current_mixin]:
+              return
+            for mixin in self.mixins[current_mixin]['mixins']:
+              RecurseMixins(mixin)
 
-        for mixin in self.configs[config]:
-          RecurseMixins(mixin)
+          for mixin in self.configs[config]:
+            RecurseMixins(mixin)
+      else:
+        errs.append('Missing "chromium" master. Please update this '
+                    'proprietary codecs check with the name of the master '
+                    'responsible for public build artifacts.')
 
     if errs:
       raise MBErr(('mb config file %s has problems:' % self.args.config_file) +
@@ -1304,11 +1311,4 @@
 
 
 if __name__ == '__main__':
-  try:
-    sys.exit(main(sys.argv[1:]))
-  except MBErr as e:
-    print(e)
-    sys.exit(1)
-  except KeyboardInterrupt:
-    print("interrupted, exiting", stream=sys.stderr)
-    sys.exit(130)
+  sys.exit(main(sys.argv[1:]))
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index 8bf8d44f..bbf6a6c 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -9,140 +9,503 @@
   # is not necessarily so (i.e., we might have mac, win, and linux
   # bots all using the 'gn_release_bot' config).
   'configs': {
-    'android_cast_gyp_debug_static_bot': ['android', 'cast', 'gyp', 'debug_static_bot'],
-    'android_clang_asan_gyp_debug_bot': ['android', 'clang', 'asan', 'gyp', 'debug_bot'],
-    'android_clang_asan_gyp_debug_trybot': ['android', 'clang', 'asan', 'gyp', 'debug_trybot'],
-    'android_gn_debug_bot': ['android', 'gn', 'debug_bot'],
-    'android_gn_debug_static_bot': ['android', 'gn', 'debug_static_bot'],
-    'android_gn_debug_static_bot_arm64': ['android', 'gn', 'debug_static_bot', 'arm64'],
-    'android_gn_debug_static_bot_mipsel': ['android', 'gn', 'debug_static_bot', 'mipsel'],
-    'android_gn_debug_static_bot_x64': ['android', 'gn', 'debug_static_bot', 'x64'],
-    'android_gn_debug_static_bot_x86': ['android', 'gn', 'debug_static_bot', 'x86'],
-    'android_gn_debug_trybot': ['android', 'gn', 'debug_trybot'],
-    'android_gn_debug_trybot_mipsel': ['android', 'gn', 'debug_trybot', 'mipsel'],
-    'android_gn_debug_trybot_x64': ['android', 'gn', 'debug_trybot', 'x64'],
-    'android_gn_debug_trybot_x86': ['android', 'gn', 'debug_trybot', 'x86'],
-    'android_gn_release_bot': ['android', 'gn', 'release_bot'],
-    'android_gn_release_trybot': ['android', 'gn', 'release_trybot'],
-    'android_without_codecs_gyp_release_bot_minimal_symbols': ['android_without_codecs', 'gyp', 'release_bot_minimal_symbols'],
-    'cast_gn_release_bot': ['cast', 'gn', 'release_bot'],
-    'cast_gn_release_trybot': ['cast', 'gn', 'release_trybot'],
-    'chromeos_gn_debug_bot': ['chromeos', 'gn', 'debug_bot'],
-    'chromeos_ozone_gn_release_bot': ['chromeos', 'ozone', 'gn', 'release_bot'],
-    'chromeos_ozone_gn_release_trybot': ['chromeos', 'ozone', 'gn', 'release_trybot'],
-    'dev_gn_debug': ['gn', 'debug', 'shared', 'full_symbols'],
-    'dev_gn_release': ['gn', 'release', 'shared'],
-    'dev_gyp_debug': ['gyp', 'debug', 'shared', 'full_symbols'],
-    'dev_gyp_release': ['gyp', 'release', 'shared'],
-    'embedded_gyp_debug_bot': ['embedded', 'gyp', 'debug_bot'],
+    'android_cast_gyp_debug_static_bot': [
+      'android', 'cast', 'gyp', 'debug_static_bot',
+    ],
+
+    'android_clang_asan_gyp_debug_bot': [
+      'android', 'clang', 'asan', 'gyp', 'debug_bot',
+    ],
+
+    'android_clang_asan_gyp_debug_trybot': [
+      'android', 'clang', 'asan', 'gyp', 'debug_trybot',
+    ],
+
+    'android_gn_debug_bot': [
+      'android', 'gn', 'debug_bot',
+    ],
+
+    'android_gn_debug_static_bot': [
+      'android', 'gn', 'debug_static_bot',
+    ],
+
+    'android_gn_debug_static_bot_arm64': [
+      'android', 'gn', 'debug_static_bot', 'arm64',
+    ],
+
+    'android_gn_debug_static_bot_mipsel': [
+      'android', 'gn', 'debug_static_bot', 'mipsel',
+    ],
+
+    'android_gn_debug_static_bot_x64': [
+      'android', 'gn', 'debug_static_bot', 'x64',
+    ],
+
+    'android_gn_debug_static_bot_x86': [
+      'android', 'gn', 'debug_static_bot', 'x86',
+    ],
+
+    'android_gn_debug_trybot': [
+      'android', 'gn', 'debug_trybot',
+    ],
+
+    'android_gn_debug_trybot_mipsel': [
+      'android', 'gn', 'debug_trybot', 'mipsel',
+    ],
+
+    'android_gn_debug_trybot_x64': [
+      'android', 'gn', 'debug_trybot', 'x64',
+    ],
+
+    'android_gn_debug_trybot_x86': [
+      'android', 'gn', 'debug_trybot', 'x86',
+    ],
+
+    'android_gn_release_bot': [
+      'android', 'gn', 'release_bot',
+    ],
+
+    'android_gn_release_trybot': [
+      'android', 'gn', 'release_trybot',
+    ],
+
+    'android_without_codecs_gyp_release_bot_minimal_symbols': [
+      'android_without_codecs', 'gyp', 'release_bot_minimal_symbols',
+    ],
+
+    'cast_gn_release_bot': [
+      'cast', 'gn', 'release_bot',
+    ],
+
+    'cast_gn_release_trybot': [
+      'cast', 'gn', 'release_trybot',
+    ],
+
+    'chromeos_gn_debug_bot': [
+      'chromeos', 'gn', 'debug_bot',
+    ],
+
+    'chromeos_ozone_gn_release_bot': [
+      'chromeos', 'ozone', 'gn', 'release_bot',
+    ],
+
+    'chromeos_ozone_gn_release_trybot': [
+      'chromeos', 'ozone', 'gn', 'release_trybot',
+    ],
+
+    'dev_gn_debug': [
+      'gn', 'debug', 'shared', 'full_symbols',
+    ],
+
+    'dev_gn_release': [
+      'gn', 'release', 'shared',
+    ],
+
+    'dev_gyp_debug': [
+      'gyp', 'debug', 'shared', 'full_symbols',
+    ],
+
+    'dev_gyp_release': [
+      'gyp', 'release', 'shared',
+    ],
+
+    'embedded_gyp_debug_bot': [
+      'embedded', 'gyp', 'debug_bot',
+    ],
 
     # This is the "deployment" config for the blimp builds. Currently
     # we want them to be debug, non-optimized builds (and we don't need any
     # chrome branding), so we don't use the "official" mixin.
-    'gn_blimp_debug': ['gn', 'blimp', 'debug'],
+    'gn_blimp_debug': [
+      'gn', 'blimp', 'debug',
+    ],
 
-    'gn_cfi_release_bot': ['gn', 'cfi', 'release_bot'],
-    'gn_cfi_release_trybot': ['gn', 'cfi', 'release_trybot'],
-    'gn_cfi_diag_release_bot': ['gn', 'cfi', 'cfi_diag', 'release_bot'],
-    'gn_debug_bot': ['gn', 'debug_bot'],
-    'gn_debug_bot_minimal_symbols': ['gn', 'debug_bot_minimal_symbols'],
-    'gn_debug_bot_minimal_symbols_x86': ['gn', 'debug_bot_minimal_symbols', 'x86'],
-    'gn_debug_static_bot': ['gn', 'debug_static_bot'],
-    'gn_linux_upload': ['gn_linux_upload', 'official', 'goma'],
-    'gn_official': ['gn', 'official'],
-    'gn_official_goma': ['gn', 'official', 'goma'],
-    'gn_official_goma_minimal_symbols_android': ['gn', 'official', 'goma', 'minimal_symbols', 'android'],
-    'gn_official_goma_minimal_symbols_android_arm64': ['gn', 'official', 'goma', 'minimal_symbols', 'android', 'arm64'],
-    'gn_release_bot': ['gn', 'release_bot'],
-    'gn_release_bot_minimal_symbols': ['gn', 'release_bot_minimal_symbols'],
-    'gn_release_bot_minimal_symbols_x86': ['gn', 'release_bot_minimal_symbols', 'x86'],
-    'gn_release_trybot': ['gn', 'release_trybot'],
-    'gn_release_trybot_x86': ['gn', 'release_trybot', 'x86'],
-    'gyp_official_goma': ['gyp', 'official', 'goma'],
-    'gyp_official_goma_chromeos': ['gyp', 'official', 'goma', 'chromeos'],
-    'gyp_official_goma_x86': ['gyp', 'official', 'goma', 'x86'],
-    'gyp_official_goma_minimal_symbols_x64': ['gyp', 'official', 'goma', 'minimal_symbols', 'x64'],
-    'gyp_official_goma_minimal_symbols_x86': ['gyp', 'official', 'goma', 'minimal_symbols', 'x86'],
-    'gyp_release_bot_android': ['gyp', 'release_bot', 'android'],
-    'gyp_release_trybot': ['gyp', 'release_trybot'],
-    'gyp_release_trybot_x64': ['gyp', 'release_trybot', 'x64'],
-    'gn_release_libfuzzer_asan': ['gn', 'release', 'libfuzzer', 'asan', 'proprietary_codecs', 'pdf_xfa'],
-    'gn_release_libfuzzer_msan': ['gn', 'release', 'libfuzzer', 'msan', 'proprietary_codecs', 'pdf_xfa'],
-    'gn_release_drmemory_drfuzz_x86': ['gn', 'release', 'drmemory', 'drfuzz', 'x86', 'proprietary_codecs'],
-    'gn_release_drmemory_drfuzz': ['gn', 'release', 'drmemory', 'drfuzz', 'proprietary_codecs'],
-    'gyp_valgrind_release_bot': ['gyp', 'valgrind', 'release_bot'],
-    'gyp_valgrind_chromeos_release_bot': ['gyp', 'chromeos', 'valgrind', 'release_bot'],
-    'gyp_drmemory_shared_release_x86': ['gyp', 'drmemory', 'shared', 'release', 'x86'],
-    'gyp_drmemory_shared_release_x64': ['gyp', 'drmemory', 'shared', 'release', 'x64'],
+    'gn_cfi_release_bot': [
+      'gn', 'cfi', 'release_bot',
+    ],
+
+    'gn_cfi_release_trybot': [
+      'gn', 'cfi', 'release_trybot',
+    ],
+
+    'gn_cfi_diag_release_bot': [
+      'gn', 'cfi', 'cfi_diag', 'release_bot',
+    ],
+
+    'gn_debug_bot': [
+      'gn', 'debug_bot',
+    ],
+
+    'gn_debug_bot_minimal_symbols': [
+      'gn', 'debug_bot_minimal_symbols',
+    ],
+
+    'gn_debug_bot_minimal_symbols_x86': [
+      'gn', 'debug_bot_minimal_symbols', 'x86',
+    ],
+
+    'gn_debug_static_bot': [
+      'gn', 'debug_static_bot',
+    ],
+
+    'gn_linux_upload': [
+      'gn_linux_upload', 'official', 'goma',
+    ],
+
+    'gn_official': [
+      'gn', 'official',
+    ],
+
+    'gn_official_goma': [
+      'gn', 'official', 'goma',
+    ],
+
+    'gn_official_goma_minimal_symbols_android': [
+      'gn', 'official', 'goma', 'minimal_symbols', 'android',
+    ],
+
+    'gn_official_goma_minimal_symbols_android_arm64': [
+      'gn', 'official', 'goma', 'minimal_symbols', 'android', 'arm64',
+    ],
+
+    'gn_release_bot': [
+      'gn', 'release_bot',
+    ],
+
+    'gn_release_bot_minimal_symbols': [
+      'gn', 'release_bot_minimal_symbols',
+    ],
+
+    'gn_release_bot_minimal_symbols_x86': [
+      'gn', 'release_bot_minimal_symbols', 'x86',
+    ],
+
+    'gn_release_trybot': [
+      'gn', 'release_trybot',
+    ],
+
+    'gn_release_trybot_x86': [
+      'gn', 'release_trybot', 'x86',
+    ],
+
+    'gyp_official_goma': [
+      'gyp', 'official', 'goma',
+    ],
+
+    'gyp_official_goma_chromeos': [
+      'gyp', 'official', 'goma', 'chromeos',
+    ],
+
+    'gyp_official_goma_x86': [
+      'gyp', 'official', 'goma', 'x86',
+    ],
+
+    'gyp_official_goma_minimal_symbols_x64': [
+      'gyp', 'official', 'goma', 'minimal_symbols', 'x64',
+    ],
+
+    'gyp_official_goma_minimal_symbols_x86': [
+      'gyp', 'official', 'goma', 'minimal_symbols', 'x86',
+    ],
+
+    'gyp_release_bot_android': [
+      'gyp', 'release_bot', 'android',
+    ],
+
+    'gyp_release_trybot': [
+      'gyp', 'release_trybot',
+    ],
+
+    'gyp_release_trybot_x64': [
+      'gyp', 'release_trybot', 'x64',
+    ],
+
+    'gn_release_libfuzzer_asan': [
+      'gn', 'release', 'libfuzzer', 'asan', 'proprietary_codecs', 'pdf_xfa',
+    ],
+
+    'gn_release_libfuzzer_msan': [
+      'gn', 'release', 'libfuzzer', 'msan', 'proprietary_codecs', 'pdf_xfa',
+    ],
+
+    'gn_release_drmemory_drfuzz_x86': [
+      'gn', 'release', 'drmemory', 'drfuzz', 'x86', 'proprietary_codecs',
+     ],
+    'gn_release_drmemory_drfuzz': [
+      'gn', 'release', 'drmemory', 'drfuzz', 'proprietary_codecs',
+    ],
+
+    'gyp_valgrind_release_bot': [
+      'gyp', 'valgrind', 'release_bot',
+    ],
+
+    'gyp_valgrind_chromeos_release_bot': [
+      'gyp', 'chromeos', 'valgrind', 'release_bot',
+    ],
+
+    'gyp_drmemory_shared_release_x86': [
+      'gyp', 'drmemory', 'shared', 'release', 'x86',
+    ],
+
+    'gyp_drmemory_shared_release_x64': [
+      'gyp', 'drmemory', 'shared', 'release', 'x64',
+    ],
 
     # This is just for completeness; any bot that uses this config
     # should never actually run MB.
-    'none': ['none'],
+    'none': [
+      'none',
+    ],
 
-    'noswarming_gn_release_bot': ['noswarming', 'gn', 'release_bot'],
-    'noswarming_gyp_release_bot': ['noswarming', 'gyp', 'release_bot'],
-    'noswarming_gyp_release_bot_mac_strip': ['noswarming', 'gyp', 'release_bot', 'mac_strip'],
-    'noswarming_gyp_release_bot_x86': ['noswarming', 'gyp', 'release_bot', 'x86'],
+    'noswarming_gn_release_bot': [
+      'noswarming', 'gn', 'release_bot',
+    ],
 
-    'swarming_android_gn_release_bot_minimal_symbols': ['swarming', 'android', 'gn', 'release_bot_minimal_symbols'],
-    'swarming_android_gyp_debug_static_bot': ['swarming', 'android', 'gyp', 'debug_static_bot'],
-    'swarming_android_gyp_debug_static_bot_arm64': ['swarming', 'android', 'gyp', 'debug_static_bot', 'arm64'],
-    'swarming_android_gyp_debug_trybot': ['swarming', 'android', 'gyp', 'debug_trybot'],
-    'swarming_android_gyp_debug_trybot_arm64': ['swarming', 'android', 'gyp', 'debug_trybot', 'arm64'],
-    'swarming_android_gyp_release_bot_minimal_symbols': ['swarming', 'android', 'gyp', 'release_bot_minimal_symbols'],
-    'swarming_android_gyp_release_trybot': ['swarming', 'android', 'gyp', 'release_trybot'],
-    'swarming_asan_lsan_gyp_release_trybot': ['swarming', 'asan', 'lsan', 'release_trybot'],
-    'swarming_msan_gyp_release_trybot': ['swarming', 'chromeos', 'msan', 'gyp', 'release_trybot'],
-    'swarming_deterministic_gyp_release_bot': ['swarming', 'deterministic', 'gyp', 'release_bot'],
-    'swarming_gpu_fyi_tests_gn_debug_bot': ['swarming', 'gpu_tests', 'internal_gles2_conform_tests', 'gn', 'debug_bot', 'angle_deqp_tests'],
-    'swarming_gpu_fyi_tests_gn_debug_trybot': ['swarming', 'gpu_tests', 'internal_gles2_conform_tests', 'gn', 'debug_trybot', 'angle_deqp_tests'],
-    'swarming_gpu_fyi_tests_gn_release_bot': ['swarming', 'gpu_tests', 'internal_gles2_conform_tests', 'gn', 'release_bot', 'angle_deqp_tests'],
-    'swarming_gpu_fyi_tests_gn_release_trybot': ['swarming', 'gpu_tests', 'internal_gles2_conform_tests', 'gn', 'release_trybot', 'angle_deqp_tests'],
-    'swarming_gpu_tests_gn_debug_bot': ['swarming', 'gpu_tests', 'gn', 'debug_bot'],
-    'swarming_gpu_tests_gn_release_bot': ['swarming', 'gpu_tests', 'gn', 'release_bot'],
-    'swarming_gpu_tests_gn_release_trybot': ['swarming', 'gpu_tests', 'gn', 'release_trybot'],
-    'swarming_gn_debug_bot': ['swarming', 'gn', 'debug_bot'],
-    'swarming_gn_debug_bot_minimal_symbols_x64': ['swarming', 'gn', 'debug_bot_minimal_symbols', 'x64'],
-    'swarming_gn_debug_bot_x64': ['swarming', 'gn', 'debug_bot', 'x64'],
-    'swarming_gn_debug_trybot': ['swarming', 'gn', 'debug_trybot'],
-    'swarming_gn_non_oilpan_debug_bot_minimal_symbols_x64': ['swarming', 'gn', 'non_oilpan', 'debug_bot_minimal_symbols', 'x64'],
-    'swarming_gn_non_oilpan_debug_bot_x64': ['swarming', 'gn', 'non_oilpan', 'debug_bot_minimal_symbols', 'x64'],
-    'swarming_gn_non_oilpan_release_bot_x64': ['swarming', 'gn', 'non_oilpan', 'release_bot', 'x64'],
-    'swarming_gn_non_oilpan_release_trybot_minimal_symbols_x64': ['swarming', 'gn', 'non_oilpan', 'release_trybot', 'minimal_symbols', 'x64'],
-    'swarming_gn_release_bot': ['swarming', 'gn', 'release_bot'],
-    'swarming_gn_release_bot_x64': ['swarming', 'gn', 'release_bot', 'x64'],
-    'swarming_gn_release_trybot': ['swarming', 'gn', 'release_bot'],
-    'swarming_gn_release_trybot_minimal_symbols_x64': ['swarming', 'gn', 'release_trybot', 'minimal_symbols', 'x64'],
-    'swarming_gyp_asan_lsan_release_bot_x64': ['swarming', 'gyp', 'asan', 'lsan', 'release_bot', 'x64'],
-    'swarming_gyp_debug_bot_minimal_symbols_x64': ['swarming', 'gyp', 'debug_bot_minimal_symbols', 'x64'],
-    'swarming_gyp_debug_bot_minimal_symbols_x86': ['swarming', 'gyp', 'debug_bot_minimal_symbols', 'x86'],
-    'swarming_gyp_debug_bot_no_symbols_x86': ['swarming', 'gyp', 'debug_bot', 'no_symbols', 'x86'],
-    'swarming_gyp_debug_bot_x64': ['swarming', 'gyp', 'debug_bot', 'x64'],
-    'swarming_gyp_debug_trybot_x86': ['swarming', 'gyp', 'debug_trybot', 'x86'],
-    'swarming_gyp_msan_release_bot_x64': ['swarming', 'gyp', 'msan', 'release_bot', 'x64'],
-    'swarming_gyp_non_oilpan_asan_lsan_release_bot_x64': ['swarming', 'gyp', 'non_oilpan', 'asan', 'lsan', 'release_bot', 'x64'],
-    'swarming_gyp_non_oilpan_debug_bot_minimal_symbols_x64': ['swarming', 'gyp', 'non_oilpan', 'debug_bot_minimal_symbols', 'x64'],
-    'swarming_gyp_non_oilpan_debug_bot_minimal_symbols_x86': ['swarming', 'gyp', 'non_oilpan', 'debug_bot_minimal_symbols', 'x86'],
-    'swarming_gyp_non_oilpan_debug_bot_x64': ['swarming', 'gyp', 'non_oilpan', 'debug_bot_minimal_symbols', 'x64'],
-    'swarming_gyp_non_oilpan_release_bot_minimal_symbols_x86': ['swarming', 'gyp', 'non_oilpan', 'release_bot', 'minimal_symbols', 'x86'],
-    'swarming_gyp_non_oilpan_release_bot_x64': ['swarming', 'gyp', 'non_oilpan', 'release_bot', 'x64'],
-    'swarming_gyp_non_oilpan_release_trybot_minimal_symbols_x64': ['swarming', 'gyp', 'non_oilpan', 'release_trybot', 'minimal_symbols', 'x64'],
-    'swarming_gyp_non_oilpan_release_trybot_minimal_symbols_x86': ['swarming', 'gyp', 'non_oilpan', 'release_trybot', 'minimal_symbols', 'x86'],
-    'swarming_gyp_release_bot': ['swarming', 'gyp', 'release_bot'],
-    'swarming_gyp_release_bot_arm': ['swarming', 'gyp', 'release_bot', 'arm', 'crosscompile'],
-    'swarming_gyp_release_bot_minimal_symbols_x64': ['swarming', 'gyp', 'release_bot_minimal_symbols', 'x64'],
-    'swarming_gyp_release_bot_minimal_symbols_x86': ['swarming', 'gyp', 'release_bot_minimal_symbols', 'x86'],
-    'swarming_gyp_release_bot_x64': ['swarming', 'gyp', 'release_bot', 'x64'],
-    'swarming_gyp_release_trybot_arm': ['swarming', 'gyp', 'release_trybot', 'arm', 'crosscompile'],
-    'swarming_gyp_release_trybot_minimal_symbols_x64': ['swarming', 'gyp', 'release_trybot', 'minimal_symbols', 'x64'],
-    'swarming_gyp_release_trybot_minimal_symbols_x86': ['swarming', 'gyp', 'release_trybot', 'minimal_symbols', 'x86'],
-    'swarming_tsan_gyp_release_trybot': ['swarming', 'disable_nacl', 'tsan', 'gyp', 'release_trybot'],
+    'noswarming_gyp_release_bot': [
+      'noswarming', 'gyp', 'release_bot',
+    ],
 
-    # Configurations that build with proprietary codecs enabled.
-    'gn_debug_bot_minimal_symbols_chrome_with_codecs': ['gn', 'debug_bot_minimal_symbols', 'chrome_with_codecs'],
-    'gn_debug_static_bot_chrome_with_codecs': ['gn', 'debug_static_bot', 'chrome_with_codecs'],
-    'gn_release_bot_chrome_with_codecs': ['gn', 'release_bot', 'chrome_with_codecs'],
-    'gn_release_bot_minimal_symbols_chrome_with_codecs': ['gn', 'release_bot_minimal_symbols', 'chrome_with_codecs'],
+    'noswarming_gyp_release_bot_mac_strip': [
+      'noswarming', 'gyp', 'release_bot', 'mac_strip',
+    ],
+
+    'noswarming_gyp_release_bot_x86': [
+      'noswarming', 'gyp', 'release_bot', 'x86',
+    ],
+
+    'swarming_android_gn_release_bot_minimal_symbols': [
+      'swarming', 'android', 'gn', 'release_bot_minimal_symbols',
+    ],
+
+    'swarming_android_gyp_debug_static_bot': [
+      'swarming', 'android', 'gyp', 'debug_static_bot',
+    ],
+
+    'swarming_android_gyp_debug_static_bot_arm64': [
+      'swarming', 'android', 'gyp', 'debug_static_bot', 'arm64',
+    ],
+
+    'swarming_android_gyp_debug_trybot': [
+      'swarming', 'android', 'gyp', 'debug_trybot',
+    ],
+
+    'swarming_android_gyp_debug_trybot_arm64': [
+      'swarming', 'android', 'gyp', 'debug_trybot', 'arm64',
+    ],
+
+    'swarming_android_gyp_release_bot_minimal_symbols': [
+      'swarming', 'android', 'gyp', 'release_bot_minimal_symbols',
+    ],
+
+    'swarming_android_gyp_release_trybot': [
+      'swarming', 'android', 'gyp', 'release_trybot',
+    ],
+
+    'swarming_asan_lsan_gyp_release_trybot': [
+      'swarming', 'asan', 'lsan', 'release_trybot',
+    ],
+
+    'swarming_msan_gyp_release_trybot': [
+      'swarming', 'chromeos', 'msan', 'gyp', 'release_trybot',
+    ],
+
+    'swarming_deterministic_gyp_release_bot': [
+      'swarming', 'deterministic', 'gyp', 'release_bot',
+    ],
+
+    'swarming_gpu_fyi_tests_gn_debug_bot': [
+      'swarming', 'gpu_tests', 'internal_gles2_conform_tests', 'gn',
+      'debug_bot', 'angle_deqp_tests',
+    ],
+
+    'swarming_gpu_fyi_tests_gn_debug_trybot': [
+      'swarming', 'gpu_tests', 'internal_gles2_conform_tests', 'gn',
+      'debug_trybot', 'angle_deqp_tests',
+    ],
+
+    'swarming_gpu_fyi_tests_gn_release_bot': [
+      'swarming', 'gpu_tests', 'internal_gles2_conform_tests', 'gn',
+      'release_bot', 'angle_deqp_tests',
+    ],
+
+    'swarming_gpu_fyi_tests_gn_release_trybot': [
+      'swarming', 'gpu_tests', 'gn', 'release_trybot',
+    ],
+
+    'swarming_gpu_tests_gn_debug_bot': [
+      'swarming', 'gpu_tests', 'gn', 'debug_bot',
+    ],
+
+    'swarming_gpu_tests_gn_release_bot': [
+      'swarming', 'gpu_tests', 'gn', 'release_bot',
+    ],
+
+    'swarming_gpu_tests_gn_release_trybot': [
+      'swarming', 'gpu_tests', 'gn', 'release_trybot',
+    ],
+
+    'swarming_gn_debug_bot': [
+      'swarming', 'gn', 'debug_bot',
+    ],
+
+    'swarming_gn_debug_bot_minimal_symbols_x64': [
+      'swarming', 'gn', 'debug_bot_minimal_symbols', 'x64',
+    ],
+
+    'swarming_gn_debug_bot_x64': [
+      'swarming', 'gn', 'debug_bot', 'x64',
+    ],
+
+    'swarming_gn_debug_trybot': [
+      'swarming', 'gn', 'debug_trybot',
+    ],
+
+    'swarming_gn_non_oilpan_debug_bot_minimal_symbols_x64': [
+      'swarming', 'gn', 'non_oilpan', 'debug_bot_minimal_symbols', 'x64',
+    ],
+
+    'swarming_gn_non_oilpan_debug_bot_x64': [
+      'swarming', 'gn', 'non_oilpan', 'debug_bot_minimal_symbols', 'x64',
+    ],
+
+    'swarming_gn_non_oilpan_release_bot_x64': [
+      'swarming', 'gn', 'non_oilpan', 'release_bot', 'x64',
+    ],
+
+    'swarming_gn_non_oilpan_release_trybot_minimal_symbols_x64': [
+      'swarming', 'gn', 'non_oilpan', 'release_trybot', 'minimal_symbols',
+      'x64',
+    ],
+
+    'swarming_gn_release_bot': [
+      'swarming', 'gn', 'release_bot',
+    ],
+
+    'swarming_gn_release_bot_x64': [
+      'swarming', 'gn', 'release_bot', 'x64',
+    ],
+
+    'swarming_gn_release_trybot': [
+      'swarming', 'gn', 'release_bot',
+    ],
+
+    'swarming_gn_release_trybot_minimal_symbols_x64': [
+      'swarming', 'gn', 'release_trybot', 'minimal_symbols', 'x64',
+    ],
+
+    'swarming_gyp_asan_lsan_release_bot_x64': [
+      'swarming', 'gyp', 'asan', 'lsan', 'release_bot', 'x64',
+    ],
+
+    'swarming_gyp_debug_bot_minimal_symbols_x64': [
+      'swarming', 'gyp', 'debug_bot_minimal_symbols', 'x64',
+    ],
+
+    'swarming_gyp_debug_bot_minimal_symbols_x86': [
+      'swarming', 'gyp', 'debug_bot_minimal_symbols', 'x86',
+    ],
+
+    'swarming_gyp_debug_bot_no_symbols_x86': [
+      'swarming', 'gyp', 'debug_bot', 'no_symbols', 'x86',
+    ],
+
+    'swarming_gyp_debug_bot_x64': [
+      'swarming', 'gyp', 'debug_bot', 'x64',
+    ],
+
+    'swarming_gyp_debug_trybot_x86': [
+      'swarming', 'gyp', 'debug_trybot', 'x86',
+    ],
+
+    'swarming_gyp_msan_release_bot_x64': [
+      'swarming', 'gyp', 'msan', 'release_bot', 'x64',
+    ],
+
+    'swarming_gyp_non_oilpan_asan_lsan_release_bot_x64': [
+      'swarming', 'gyp', 'non_oilpan', 'asan', 'lsan', 'release_bot', 'x64',
+    ],
+
+    'swarming_gyp_non_oilpan_debug_bot_minimal_symbols_x64': [
+      'swarming', 'gyp', 'non_oilpan', 'debug_bot_minimal_symbols', 'x64',
+    ],
+
+    'swarming_gyp_non_oilpan_debug_bot_minimal_symbols_x86': [
+      'swarming', 'gyp', 'non_oilpan', 'debug_bot_minimal_symbols', 'x86',
+    ],
+
+    'swarming_gyp_non_oilpan_debug_bot_x64': [
+      'swarming', 'gyp', 'non_oilpan', 'debug_bot_minimal_symbols', 'x64',
+    ],
+
+    'swarming_gyp_non_oilpan_release_bot_minimal_symbols_x86': [
+      'swarming', 'gyp', 'non_oilpan', 'release_bot', 'minimal_symbols', 'x86',
+    ],
+
+    'swarming_gyp_non_oilpan_release_bot_x64': [
+      'swarming', 'gyp', 'non_oilpan', 'release_bot', 'x64',
+    ],
+
+    'swarming_gyp_non_oilpan_release_trybot_minimal_symbols_x64': [
+      'swarming', 'gyp', 'non_oilpan', 'release_trybot', 'minimal_symbols',
+      'x64',
+    ],
+
+    'swarming_gyp_non_oilpan_release_trybot_minimal_symbols_x86': [
+      'swarming', 'gyp', 'non_oilpan', 'release_trybot', 'minimal_symbols',
+      'x86',
+    ],
+
+    'swarming_gyp_release_bot': [
+      'swarming', 'gyp', 'release_bot',
+    ],
+
+    'swarming_gyp_release_bot_arm': [
+      'swarming', 'gyp', 'release_bot', 'arm', 'crosscompile',
+    ],
+
+    'swarming_gyp_release_bot_minimal_symbols_x64': [
+      'swarming', 'gyp', 'release_bot_minimal_symbols', 'x64',
+    ],
+
+    'swarming_gyp_release_bot_minimal_symbols_x86': [
+      'swarming', 'gyp', 'release_bot_minimal_symbols', 'x86',
+    ],
+
+    'swarming_gyp_release_bot_x64': [
+      'swarming', 'gyp', 'release_bot', 'x64',
+    ],
+
+    'swarming_gyp_release_trybot_arm': [
+      'swarming', 'gyp', 'release_trybot', 'arm', 'crosscompile',
+    ],
+
+    'swarming_gyp_release_trybot_minimal_symbols_x64': [
+      'swarming', 'gyp', 'release_trybot', 'minimal_symbols', 'x64',
+    ],
+
+    'swarming_gyp_release_trybot_minimal_symbols_x86': [
+      'swarming', 'gyp', 'release_trybot', 'minimal_symbols', 'x86',
+    ],
+
+    'swarming_tsan_gyp_release_trybot': [
+      'swarming', 'disable_nacl', 'tsan', 'gyp', 'release_trybot',
+    ],
+
+    'gn_debug_bot_minimal_symbols_chrome_with_codecs': [
+      'gn', 'debug_bot_minimal_symbols', 'chrome_with_codecs',
+    ],
+
+    'gn_debug_static_bot_chrome_with_codecs': [
+      'gn', 'debug_static_bot', 'chrome_with_codecs',
+    ],
+
+    'gn_release_bot_chrome_with_codecs': [
+      'gn', 'release_bot', 'chrome_with_codecs',
+    ],
+
+    'gn_release_bot_minimal_symbols_chrome_with_codecs': [
+      'gn', 'release_bot_minimal_symbols', 'chrome_with_codecs',
+    ],
 
     # This indicates that we haven't yet set up this bot w/ MB. This is
     # different from 'none' in that a bot set to 'none' should never do
@@ -150,7 +513,9 @@
     # added the entries yet.
     # 'tbd': ['none'],
 
-    'win_clang_debug_bot': ['gn', 'clang', 'debug_bot_minimal_symbols'],
+    'win_clang_debug_bot': [
+      'gn', 'clang', 'debug_bot_minimal_symbols',
+    ],
   },
 
   # This is a list of configs that do not actually exist on any bot
@@ -179,10 +544,10 @@
   # This is a dict mapping a given 'mixin' name to a dict of settings that
   # mb should use. See //tools/mb/docs/user_guide.md for more information.
   'mixins': {
-    # We build Android with codecs on most bots to ensure maximum test coverage,
-    # but use 'android_without_codecs' on bots responsible for building publicly
-    # advertised non-Official Android builds -- which are not allowed to have
-    # proprietary codecs enabled.
+    # We build Android with codecs on most bots to ensure maximum test
+    # coverage, but use 'android_without_codecs' on bots responsible for
+    # building publicly advertised non-Official Android builds --
+    # which are not allowed to have proprietary codecs enabled.
     'android': {
       'mixins': ['android_without_codecs', 'chrome_with_codecs'],
     },
@@ -221,10 +586,13 @@
       'gyp_defines': 'asan=1',
     },
 
-    # Removes dependencies on X11 and audio libraries for a containerized build.
+    # Removes dependencies on X11 and audio libraries for a containerized
+    # build.
     'blimp': {
-      'gn_args': "use_aura=true use_ozone=true use_alsa=false use_pulseaudio=false use_cups=false use_glib=false",
-      'gyp_defines': 'use_aura=1 use_ozone=1 use_alsa=0 use_pulseaudio=0 use_cups=0 use_glib=0',
+      'gn_args': ('use_aura=true use_ozone=true use_alsa=false '
+                  'use_pulseaudio=false use_cups=false use_glib=false'),
+      'gyp_defines': ('use_aura=1 use_ozone=1 use_alsa=0 '
+                      'use_pulseaudio=0 use_cups=0 use_glib=0'),
     },
 
     'cast': {
@@ -364,8 +732,10 @@
     },
 
     'msan': {
-      'gn_args': 'is_msan=true msan_track_origins=2 use_prebuilt_instrumented_libraries=true',
-      'gyp_defines': 'msan=1 msan_track_origins=2 use_prebuilt_instrumented_libraries=1',
+      'gn_args': ('is_msan=true msan_track_origins=2 '
+                  'use_prebuilt_instrumented_libraries=true'),
+      'gyp_defines': ('msan=1 msan_track_origins=2 '
+                      'use_prebuilt_instrumented_libraries=1'),
     },
 
     'no_symbols': {
@@ -394,7 +764,8 @@
     },
 
     'official': {
-      'gn_args': 'is_chrome_branded=true is_official_build=true is_debug=false',
+      'gn_args': ('is_chrome_branded=true is_official_build=true '
+                  'is_debug=false'),
       'gyp_defines': 'branding=Chrome buildtype=Official',
     },
 
@@ -482,8 +853,8 @@
   'masters': {
     # Take care when changing any of these builders to ensure that you do not
     # include a configuration with 'chrome_with_codecs' since these builders
-    # generated publicly advertised non-Official builds which are not allowed to
-    # have proprietary codecs enabled.
+    # generated publicly advertised non-Official builds which are not allowed
+    # to have proprietary codecs enabled.
     'chromium': {
       'Win': 'noswarming_gyp_release_bot',
       'Mac': 'noswarming_gyp_release_bot_mac_strip',
@@ -506,7 +877,8 @@
       'Lollipop Tablet Tester': 'android_gn_debug_static_bot',
       'Marshmallow 64 bit Tester': 'android_gn_debug_static_bot_arm64',
       'Marshmallow Tablet Tester': 'android_gn_debug_static_bot',
-      'Android Swarm Builder': 'swarming_android_gn_release_bot_minimal_symbols',
+      'Android Swarm Builder':
+        'swarming_android_gn_release_bot_minimal_symbols',
     },
     'chromium.chrome': {
       'Google Chrome Win': 'gyp_official_goma_minimal_symbols_x86',
@@ -520,7 +892,8 @@
       'Linux ChromiumOS GN (dbg)': 'chromeos_gn_debug_bot',
     },
     'chromium.linux': {
-      'Android Arm64 Builder (dbg)': 'swarming_android_gyp_debug_static_bot_arm64',
+      'Android Arm64 Builder (dbg)':
+        'swarming_android_gyp_debug_static_bot_arm64',
       'Android Builder': 'swarming_android_gyp_release_bot_minimal_symbols',
       'Android Builder (dbg)': 'swarming_android_gyp_debug_static_bot',
       'Android Clang Builder (dbg)': 'android_clang_asan_gyp_debug_bot',
@@ -548,7 +921,8 @@
     },
     'chromium.perf': {
       'Android Builder': 'gn_official_goma_minimal_symbols_android',
-      'Android arm64 Builder': 'gn_official_goma_minimal_symbols_android_arm64',
+      'Android arm64 Builder':
+        'gn_official_goma_minimal_symbols_android_arm64',
       'Win Builder': 'gyp_official_goma_minimal_symbols_x86',
       'Win x64 Builder': 'gyp_official_goma_minimal_symbols_x64',
       'Mac Builder': 'gyp_official_goma',
@@ -566,11 +940,14 @@
       'WebKit Win7': 'none',
       'WebKit Win10': 'none',
       'WebKit Win x64 Builder': 'swarming_gyp_release_bot_minimal_symbols_x64',
-      'WebKit Win non-Oilpan': 'swarming_gyp_non_oilpan_release_bot_minimal_symbols_x86',
+      'WebKit Win non-Oilpan':
+        'swarming_gyp_non_oilpan_release_bot_minimal_symbols_x86',
       'WebKit Win Builder (dbg)': 'swarming_gyp_debug_bot_minimal_symbols_x86',
       'WebKit Win7 (dbg)': 'none',
-      'WebKit Win non-Oilpan (dbg)': 'swarming_gyp_non_oilpan_debug_bot_minimal_symbols_x86',
-      'WebKit Win x64 Builder (dbg)': 'swarming_gyp_debug_bot_minimal_symbols_x64',
+      'WebKit Win non-Oilpan (dbg)':
+        'swarming_gyp_non_oilpan_debug_bot_minimal_symbols_x86',
+      'WebKit Win x64 Builder (dbg)':
+        'swarming_gyp_debug_bot_minimal_symbols_x64',
       'WebKit Mac Builder': 'swarming_gyp_release_bot_x64',
       'WebKit Mac10.11 (retina)': 'swarming_gyp_release_bot_x64',
       'WebKit Mac10.10': 'none',
@@ -581,9 +958,11 @@
       'WebKit Mac non-Oilpan (dbg)': 'swarming_gyp_non_oilpan_debug_bot_x64',
       'WebKit Linux': 'swarming_gn_release_bot_x64',
       'WebKit Linux Trusty': 'swarming_gn_release_bot_x64',
-      'WebKit Linux non-Oilpan Builder': 'swarming_gn_non_oilpan_release_bot_x64',
+      'WebKit Linux non-Oilpan Builder':
+        'swarming_gn_non_oilpan_release_bot_x64',
       'WebKit Linux ASAN': 'swarming_gyp_asan_lsan_release_bot_x64',
-      'WebKit Linux non-Oilpan ASAN': 'swarming_gyp_non_oilpan_asan_lsan_release_bot_x64',
+      'WebKit Linux non-Oilpan ASAN':
+        'swarming_gyp_non_oilpan_asan_lsan_release_bot_x64',
       'WebKit Linux MSAN': 'swarming_gyp_msan_release_bot_x64',
       'WebKit Linux Leak': 'swarming_gn_release_bot_x64',
       'WebKit Linux non-Oilpan Leak': 'swarming_gn_non_oilpan_release_bot_x64',
@@ -632,7 +1011,8 @@
       'Windows Browser (DrMemory full) (10)': 'none',
       'Windows Browser (DrMemory full) (11)': 'none',
       'Windows Browser (DrMemory full) (12)': 'none',
-      'Chromium Windows Builder (DrMemory x64)': 'gyp_drmemory_shared_release_x64',
+      'Chromium Windows Builder (DrMemory x64)':
+        'gyp_drmemory_shared_release_x64',
       'Windows Unit (DrMemory x64)': 'none',
     },
     'chromium.fyi': {
@@ -694,7 +1074,8 @@
     'tryserver.blink': {
       'linux_blink_dbg': 'swarming_gn_debug_bot_minimal_symbols_x64',
       'linux_blink_compile_dbg': 'swarming_gn_debug_bot_minimal_symbols_x64',
-      'linux_blink_compile_rel': 'swarming_gn_release_trybot_minimal_symbols_x64',
+      'linux_blink_compile_rel':
+        'swarming_gn_release_trybot_minimal_symbols_x64',
       'linux_blink_rel': 'swarming_gn_release_trybot_minimal_symbols_x64',
       'mac_blink_dbg': 'swarming_gyp_debug_bot_minimal_symbols_x64',
       'mac_blink_compile_dbg': 'swarming_gyp_debug_bot_minimal_symbols_x64',
@@ -702,18 +1083,29 @@
       'mac_blink_rel': 'swarming_gyp_release_trybot_minimal_symbols_x64',
       'win_blink_dbg': 'swarming_gyp_debug_bot_minimal_symbols_x86',
       'win_blink_compile_dbg': 'swarming_gyp_debug_bot_minimal_symbols_x86',
-      'win_blink_compile_rel': 'swarming_gyp_release_trybot_minimal_symbols_x86',
+      'win_blink_compile_rel':
+        'swarming_gyp_release_trybot_minimal_symbols_x86',
       'win_blink_rel': 'swarming_gyp_release_trybot_minimal_symbols_x86',
-      'linux_blink_oilpan_dbg': 'swarming_gn_non_oilpan_debug_bot_minimal_symbols_x64',
-      'linux_blink_oilpan_rel': 'swarming_gn_non_oilpan_release_trybot_minimal_symbols_x64',
-      'linux_blink_oilpan_compile_rel': 'swarming_gn_non_oilpan_release_trybot_minimal_symbols_x64',
-      'mac_blink_oilpan_dbg': 'swarming_gyp_non_oilpan_debug_bot_minimal_symbols_x64',
-      'mac_blink_oilpan_rel': 'swarming_gyp_non_oilpan_release_trybot_minimal_symbols_x64',
-      'mac_blink_oilpan_compile_rel': 'swarming_gyp_non_oilpan_release_trybot_minimal_symbols_x64',
-      'win_blink_oilpan_dbg': 'swarming_gyp_non_oilpan_debug_bot_minimal_symbols_x86',
-      'win_blink_oilpan_rel': 'swarming_gyp_non_oilpan_release_trybot_minimal_symbols_x86',
-      'win_blink_oilpan_compile_rel': 'swarming_gyp_non_oilpan_release_trybot_minimal_symbols_x86',
-      'linux_blink_rel_ng': 'swarming_gn_release_trybot_minimal_symbols_x64',
+      'linux_blink_oilpan_dbg':
+        'swarming_gn_non_oilpan_debug_bot_minimal_symbols_x64',
+      'linux_blink_oilpan_rel':
+        'swarming_gn_non_oilpan_release_trybot_minimal_symbols_x64',
+      'linux_blink_oilpan_compile_rel':
+        'swarming_gn_non_oilpan_release_trybot_minimal_symbols_x64',
+      'mac_blink_oilpan_dbg':
+        'swarming_gyp_non_oilpan_debug_bot_minimal_symbols_x64',
+      'mac_blink_oilpan_rel':
+        'swarming_gyp_non_oilpan_release_trybot_minimal_symbols_x64',
+      'mac_blink_oilpan_compile_rel':
+        'swarming_gyp_non_oilpan_release_trybot_minimal_symbols_x64',
+      'win_blink_oilpan_dbg':
+        'swarming_gyp_non_oilpan_debug_bot_minimal_symbols_x86',
+      'win_blink_oilpan_rel':
+        'swarming_gyp_non_oilpan_release_trybot_minimal_symbols_x86',
+      'win_blink_oilpan_compile_rel':
+        'swarming_gyp_non_oilpan_release_trybot_minimal_symbols_x86',
+      'linux_blink_rel_ng':
+        'swarming_gn_release_trybot_minimal_symbols_x64',
       'blink_presubmit': 'none',
     },
     'tryserver.chromium.android': {
@@ -743,7 +1135,8 @@
       'linux_chromium_rel_ng': 'swarming_gpu_tests_gn_release_trybot',
       'linux_chromium_cfi_rel_ng': 'gn_cfi_release_trybot',
       'linux_chromium_gn_chromeos_rel': 'chromeos_ozone_gn_release_trybot',
-      'linux_blink_oilpan_rel': 'swarming_gn_non_oilpan_release_trybot_minimal_symbols_x64',
+      'linux_blink_oilpan_rel':
+        'swarming_gn_non_oilpan_release_trybot_minimal_symbols_x64',
       'linux_chromium_compile_dbg_ng': 'swarming_gn_debug_trybot',
       'linux_chromium_dbg_ng': 'swarming_gn_debug_trybot',
       'linux_chromium_gn_chromeos_dbg': 'chromeos_gn_debug_bot',
@@ -760,7 +1153,8 @@
       'cast_shell_linux': 'cast_gn_release_trybot',
       'linux_deterministic': 'swarming_deterministic_gyp_release_bot',
       'linux_ecs_ozone': 'embedded_gyp_debug_bot',
-      'linux_optional_gpu_tests_rel': 'swarming_gpu_fyi_tests_gn_release_trybot',
+      'linux_optional_gpu_tests_rel':
+        'swarming_gpu_fyi_tests_gn_release_trybot',
     },
     'tryserver.chromium.mac': {
       'mac_chromium_gn_dbg': 'gn_debug_static_bot',
@@ -769,8 +1163,10 @@
       'mac_chromium_clang_upload': 'gn_release_bot',
     },
     'tryserver.chromium.perf': {
-      'android_perf_bisect_builder': 'gn_official_goma_minimal_symbols_android',
-      'android_arm64_perf_bisect_builder': 'gn_official_goma_minimal_symbols_android_arm64',
+      'android_perf_bisect_builder':
+        'gn_official_goma_minimal_symbols_android',
+      'android_arm64_perf_bisect_builder':
+        'gn_official_goma_minimal_symbols_android_arm64',
       'linux_perf_bisect_builder': 'gn_official_goma',
       'mac_perf_bisect_builder': 'gyp_official_goma',
       'win_perf_bisect_builder': 'gyp_official_goma_minimal_symbols_x86',
@@ -792,11 +1188,14 @@
       'android_nexus5_perf_bisect': 'gn_official_goma_minimal_symbols_android',
       'android_nexus6_perf_bisect': 'gn_official_goma_minimal_symbols_android',
       'android_nexus7_perf_bisect': 'gn_official_goma_minimal_symbols_android',
-      'android_nexus9_perf_bisect': 'gn_official_goma_minimal_symbols_android_arm64',
+      'android_nexus9_perf_bisect':
+        'gn_official_goma_minimal_symbols_android_arm64',
       'android_s5_perf_bisect': 'gn_official_goma_minimal_symbols_android',
       'android_s5_perf_cq': 'gn_official_goma_minimal_symbols_android',
-      'android_nexus5X_perf_bisect': 'gn_official_goma_minimal_symbols_android',
-      'android_webview_aosp_perf_bisect': 'gn_official_goma_minimal_symbols_android',
+      'android_nexus5X_perf_bisect':
+        'gn_official_goma_minimal_symbols_android',
+      'android_webview_aosp_perf_bisect':
+        'gn_official_goma_minimal_symbols_android',
       'linux_perf_cq': 'gn_official_goma',
       'mac_retina_perf_cq': 'gyp_official_goma',
       'winx64_10_perf_cq': 'gyp_official_goma_minimal_symbols_x64',
diff --git a/tools/mb/mb_unittest.py b/tools/mb/mb_unittest.py
index 6a0218c..f3d42b23 100755
--- a/tools/mb/mb_unittest.py
+++ b/tools/mb/mb_unittest.py
@@ -198,17 +198,11 @@
         mbw.files[path] = contents
     return mbw
 
-  def check(self, args, mbw=None, files=None, out=None, err=None, ret=None,
-            exception=None):
+  def check(self, args, mbw=None, files=None, out=None, err=None, ret=None):
     if not mbw:
       mbw = self.fake_mbw(files)
-    mbw.ParseArgs(args)
 
-    actual_ret = None
-    if exception is not None:
-      self.assertRaisesRegexp(Exception, exception, mbw.args.func)
-    else:
-      actual_ret = mbw.args.func()
+    actual_ret = mbw.Main(args)
 
     self.assertEqual(actual_ret, ret)
     if out is not None:
@@ -446,12 +440,14 @@
       sys.stdout = orig_stdout
 
   def test_validate(self):
-    self.check(['validate'], ret=0)
+    mbw = self.fake_mbw()
+    mbw.files[mbw.default_config] = TEST_CONFIG
+    self.check(['validate'], mbw=mbw, ret=0)
 
   def test_bad_validate(self):
     mbw = self.fake_mbw()
     mbw.files[mbw.default_config] = TEST_BAD_CONFIG
-    self.check(['validate'], mbw=mbw, exception=TEST_BAD_CONFIG_ERR)
+    self.check(['validate'], mbw=mbw, ret=1)
 
 
 if __name__ == '__main__':
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index a5fa035..60140b33 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -45951,6 +45951,15 @@
   </summary>
 </histogram>
 
+<histogram name="ServiceWorker.StartWorker.Purpose"
+    enum="ServiceWorkerMetrics.EventType">
+  <owner>falken@chromium.org</owner>
+  <summary>
+    The purpose for starting up a service worker. Recorded only for installed
+    workers.
+  </summary>
+</histogram>
+
 <histogram name="ServiceWorker.StartWorker.Status"
     enum="ServiceWorkerStatusCode">
   <owner>falken@chromium.org</owner>
@@ -45971,6 +45980,15 @@
   </summary>
 </histogram>
 
+<histogram name="ServiceWorker.StartWorker.Timeout.StartPurpose"
+    enum="ServiceWorkerMetrics.EventType">
+  <owner>falken@chromium.org</owner>
+  <summary>
+    Records the start purpose for a service worker that timed out while starting
+    up. Recorded only for installed workers.
+  </summary>
+</histogram>
+
 <histogram name="ServiceWorker.StartWorker.TimeoutPhase"
     enum="EmbeddedWorkerStartingPhase">
   <owner>falken@chromium.org</owner>
@@ -80171,13 +80189,19 @@
 <enum name="ServiceWorkerMetrics.EventType" type="int">
   <int value="0" label="ACTIVATE"/>
   <int value="1" label="INSTALL"/>
-  <int value="2" label="FETCH"/>
+  <int value="2" label="FETCH (deprecated)"/>
   <int value="3" label="SYNC"/>
   <int value="4" label="NOTIFICATION_CLICK"/>
   <int value="5" label="PUSH"/>
   <int value="6" label="GEOFENCING"/>
   <int value="7" label="SERVICE_PORT_CONNECT"/>
   <int value="8" label="MESSAGE"/>
+  <int value="9" label="NOTIFICATION_CLOSE"/>
+  <int value="10" label="FETCH_MAIN_FRAME"/>
+  <int value="11" label="FETCH_SUB_FRAME"/>
+  <int value="12" label="FETCH_SHARED_WORKER"/>
+  <int value="13" label="FETCH_SUB_RESOURCE"/>
+  <int value="14" label="UNKOWN"/>
 </enum>
 
 <enum name="ServiceWorkerReadResponseResult" type="int">
diff --git a/ui/file_manager/video_player/js/test_util.js b/ui/file_manager/video_player/js/test_util.js
index 2415cd6..9e5d019 100644
--- a/ui/file_manager/video_player/js/test_util.js
+++ b/ui/file_manager/video_player/js/test_util.js
@@ -14,7 +14,7 @@
     var contentWindow = window.background.appWindows[appId].contentWindow;
     if (contentWindow &&
         contentWindow.document.title === filename) {
-      var element = contentWindow.document.querySelector('video[src]');
+      var element = contentWindow.document.querySelector('video');
       if (element && testFunction(element))
         return true;
     }
diff --git a/ui/file_manager/video_player/js/video_player.js b/ui/file_manager/video_player/js/video_player.js
index bed41ba5..469e09e9 100644
--- a/ui/file_manager/video_player/js/video_player.js
+++ b/ui/file_manager/video_player/js/video_player.js
@@ -376,8 +376,11 @@
       this.videoElement_ = document.createElement('video');
       getRequiredElement('video-container').appendChild(this.videoElement_);
 
+      var videoUrl = video.toURL();
       this.controls.attachMedia(this.videoElement_);
-      this.videoElement_.src = video.toURL();
+      var source = document.createElement('source');
+      source.src = videoUrl;
+      this.videoElement_.appendChild(source);
 
       media.isAvailableForCast().then(function(result) {
         if (result)
@@ -388,9 +391,17 @@
         videoPlayerElement.setAttribute('castable', true);
       });
 
-      videoElementInitializePromise = Promise.resolve();
+      videoElementInitializePromise = this.searchSubtitle_(videoUrl)
+          .then(function(subltitleUrl) {
+            if (subltitleUrl) {
+              var track = document.createElement('track');
+              track.src = subltitleUrl;
+              track.kind = 'subtitles';
+              track.default = true;
+              this.videoElement_.appendChild(track);
+            }
+          }.bind(this));
     }
-
     videoElementInitializePromise
         .then(function() {
           var handler = function(currentPos) {
@@ -413,8 +424,16 @@
             chrome.power.releaseKeepAwake();
             this.updateInactivityWatcherState_();
           }.wrap(this));
-
-          this.videoElement_.load();
+          // TODO(ryoh):
+          // If you modify the video element that is already inserted,
+          // you have to call load() method.
+          // https://dev.w3.org/html5/spec-author-view/video.html
+          // But we always create new video element (see above),
+          // we don't have to call load().
+          // If you call load() method here,
+          // you can't see subtitles.
+          // (It might be a bug: https://crbug.com/594537)
+          //this.videoElement_.load();
           callback();
         }.bind(this))
         // In case of error.
@@ -433,6 +452,24 @@
 };
 
 /**
+ * Search subtile file corresponding to a video.
+ * @param {string} url a url of a video.
+ * @return {string} a url of subtitle file, or an empty string.
+ */
+VideoPlayer.prototype.searchSubtitle_ = function(url) {
+  var baseUrl = util.splitExtension(url)[0];
+  var resolveLocalFileSystemWithExtension = function(extension) {
+    return new Promise(
+        window.webkitResolveLocalFileSystemURL.bind(null, baseUrl + extension));
+  };
+  return resolveLocalFileSystemWithExtension('.vtt').then(function(subtitle) {
+    return subtitle.toURL();
+  }).catch(function() {
+    return '';
+  });
+};
+
+/**
  * Plays the first video.
  */
 VideoPlayer.prototype.playFirstVideo = function() {