diff --git a/DEPS b/DEPS
index 1d24957..a940ee5 100644
--- a/DEPS
+++ b/DEPS
@@ -40,11 +40,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': '1026ccf1d2de57ae6e7d2f30ea92c245942121d3',
+  'skia_revision': 'a16339297859f37df69230e64f05624cef511ad3',
   # 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': 'b9b7cf76952d18de434ef9b53edf2a11e12bb92f',
+  'v8_revision': 'c9306576dd744f56f796f9129200e17d448d5b55',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling swarming_client
   # and whatever else without interference from each other.
@@ -64,7 +64,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
-  'pdfium_revision': '591ed144f8dfe4b2915f01f1cc725f584d498a3f',
+  'pdfium_revision': '661008dde7356ee2ed69787125863539b73b041c',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling openmax_dl
   # and whatever else without interference from each other.
@@ -96,7 +96,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling catapult
   # and whatever else without interference from each other.
-  'catapult_revision': '487c2d0050eb9d13f8438ac9a701acc4d3f30d56',
+  'catapult_revision': '7ec93bcc8dd05f69996acaf829267c777da28a51',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -285,7 +285,7 @@
     Var('chromium_git') + '/external/py_trace_event.git' + '@' + 'dd463ea9e2c430de2b9e53dea57a77b4c3ac9b30',
 
   'src/third_party/dom_distiller_js/dist':
-    Var('chromium_git') + '/external/github.com/chromium/dom-distiller-dist.git' + '@' + '241e65eb93dd3e0dec2e0d3e0e0cac7a0e74e82c',
+    Var('chromium_git') + '/external/github.com/chromium/dom-distiller-dist.git' + '@' + '2fb636d492d74b91cbbd357da0281b6f0de19ee8',
 
   'src/third_party/catapult':
     Var('chromium_git') + '/external/github.com/catapult-project/catapult.git' + '@' +
diff --git a/ash/mus/bridge/wm_shell_mus.cc b/ash/mus/bridge/wm_shell_mus.cc
index 8794f8554..1046a5a 100644
--- a/ash/mus/bridge/wm_shell_mus.cc
+++ b/ash/mus/bridge/wm_shell_mus.cc
@@ -142,9 +142,13 @@
   SetKeyboardUI(KeyboardUIMus::Create(window_manager_->connector()));
 
   wallpaper_delegate()->InitializeWallpaper();
+
+  window_manager->activation_client()->AddObserver(this);
 }
 
 WmShellMus::~WmShellMus() {
+  window_manager_->activation_client()->RemoveObserver(this);
+
   // This order mirrors that of Shell.
 
   // Destroy maximize mode controller early on since it has some observers which
diff --git a/ash/mus/window_manager.cc b/ash/mus/window_manager.cc
index 5479714..f3ebdc9 100644
--- a/ash/mus/window_manager.cc
+++ b/ash/mus/window_manager.cc
@@ -137,6 +137,10 @@
   lookup_.reset(new WmLookupMus);
 }
 
+aura::client::ActivationClient* WindowManager::activation_client() {
+  return focus_controller_.get();
+}
+
 aura::Window* WindowManager::NewTopLevelWindow(
     ui::mojom::WindowType window_type,
     std::map<std::string, std::vector<uint8_t>>* properties) {
diff --git a/ash/mus/window_manager.h b/ash/mus/window_manager.h
index 1ef35062..6042278 100644
--- a/ash/mus/window_manager.h
+++ b/ash/mus/window_manager.h
@@ -20,6 +20,12 @@
 #include "ui/aura/mus/window_manager_delegate.h"
 #include "ui/aura/mus/window_tree_client_delegate.h"
 
+namespace aura {
+namespace client {
+class ActivationClient;
+}
+}
+
 namespace base {
 class SequencedWorkerPool;
 }
@@ -85,6 +91,8 @@
 
   ::wm::FocusController* focus_controller() { return focus_controller_.get(); }
 
+  aura::client::ActivationClient* activation_client();
+
   service_manager::Connector* connector() { return connector_; }
 
   aura::PropertyConverter* property_converter() {
diff --git a/base/timer/timer.cc b/base/timer/timer.cc
index 6e86c11c..6ec18f1 100644
--- a/base/timer/timer.cc
+++ b/base/timer/timer.cc
@@ -107,12 +107,6 @@
   return delay_;
 }
 
-TimeDelta Timer::GetTimeToCallback() const {
-  if (!user_task_)
-    return TimeDelta::Max();
-  return scheduled_run_time_ - Now();
-}
-
 void Timer::SetTaskRunner(scoped_refptr<SingleThreadTaskRunner> task_runner) {
   // Do not allow changing the task runner once something has been scheduled.
   DCHECK_EQ(thread_id_, 0);
diff --git a/base/timer/timer.h b/base/timer/timer.h
index c328dc65..50aedbd 100644
--- a/base/timer/timer.h
+++ b/base/timer/timer.h
@@ -100,11 +100,6 @@
   // Returns the current delay for this timer.
   virtual TimeDelta GetCurrentDelay() const;
 
-  // Returns an estimated time to the timer calling the user_task_ back.
-  // Note that the time may be negative if the timer has not been started,
-  // is late to call back or has done its last call back.
-  virtual TimeDelta GetTimeToCallback() const;
-
   // Set the task runner on which the task should be scheduled. This method can
   // only be called before any tasks have been scheduled. The task runner must
   // run tasks on the same thread the timer is used on.
diff --git a/base/timer/timer_unittest.cc b/base/timer/timer_unittest.cc
index 58029be..7c3c107 100644
--- a/base/timer/timer_unittest.cc
+++ b/base/timer/timer_unittest.cc
@@ -623,75 +623,6 @@
   EXPECT_TRUE(timer.IsRunning());
 }
 
-//-----------------------------------------------------------------------------
-
-TEST(TimerTest, RetainRepeatGetTimeToCallback) {
-  scoped_refptr<TestMockTimeTaskRunner> task_runner(
-      new TestMockTimeTaskRunner(Time::Now(), TimeTicks::Now()));
-  std::unique_ptr<TickClock> tick_clock(task_runner->GetMockTickClock());
-  MessageLoop message_loop;
-  message_loop.SetTaskRunner(task_runner);
-  Timer timer(true, true, tick_clock.get());
-  timer.Start(FROM_HERE, TimeDelta::FromSeconds(2), Bind(&TimerTestCallback));
-  EXPECT_EQ(TimeDelta::FromSeconds(2), timer.GetTimeToCallback());
-  task_runner->FastForwardBy(TimeDelta::FromSeconds(2));
-  EXPECT_EQ(TimeDelta::FromSeconds(2), timer.GetTimeToCallback());
-  timer.Stop();
-  task_runner->FastForwardBy(TimeDelta::FromSeconds(2));
-  EXPECT_EQ(TimeDelta::FromSeconds(0), timer.GetTimeToCallback());
-  task_runner->FastForwardBy(TimeDelta::FromSeconds(2));
-  EXPECT_EQ(TimeDelta::FromSeconds(-2), timer.GetTimeToCallback());
-}
-
-TEST(TimerTest, RetainNonRepeatGetTimeToCallback) {
-  scoped_refptr<TestMockTimeTaskRunner> task_runner(
-      new TestMockTimeTaskRunner(Time::Now(), TimeTicks::Now()));
-  std::unique_ptr<TickClock> tick_clock(task_runner->GetMockTickClock());
-  MessageLoop message_loop;
-  message_loop.SetTaskRunner(task_runner);
-  Timer timer(true, false, tick_clock.get());
-  timer.Start(FROM_HERE, TimeDelta::FromSeconds(2), Bind(&TimerTestCallback));
-  EXPECT_EQ(TimeDelta::FromSeconds(2), timer.GetTimeToCallback());
-  task_runner->FastForwardBy(TimeDelta::FromSeconds(3));
-  EXPECT_EQ(TimeDelta::FromSeconds(-1), timer.GetTimeToCallback());
-}
-
-TEST(TimerTest, OneShotTimerWithTickClockGetTimeToCallback) {
-  scoped_refptr<TestMockTimeTaskRunner> task_runner(
-      new TestMockTimeTaskRunner(Time::Now(), TimeTicks::Now()));
-  std::unique_ptr<TickClock> tick_clock(task_runner->GetMockTickClock());
-  MessageLoop message_loop;
-  message_loop.SetTaskRunner(task_runner);
-  Receiver receiver;
-  OneShotTimer timer(tick_clock.get());
-  EXPECT_EQ(TimeDelta::Max(), timer.GetTimeToCallback());
-  timer.Start(FROM_HERE, TimeDelta::FromSeconds(2),
-              Bind(&Receiver::OnCalled, Unretained(&receiver)));
-  EXPECT_EQ(TimeDelta::FromSeconds(2), timer.GetTimeToCallback());
-  task_runner->FastForwardBy(TimeDelta::FromSeconds(1));
-  EXPECT_EQ(TimeDelta::FromSeconds(1), timer.GetTimeToCallback());
-  task_runner->FastForwardBy(TimeDelta::FromSeconds(1));
-  EXPECT_TRUE(receiver.WasCalled());
-  EXPECT_EQ(TimeDelta::Max(), timer.GetTimeToCallback());
-}
-
-TEST(TimerTest, RepeatingTimerWithTickClockTimeToCallback) {
-  scoped_refptr<TestMockTimeTaskRunner> task_runner(
-      new TestMockTimeTaskRunner(Time::Now(), TimeTicks::Now()));
-  std::unique_ptr<TickClock> tick_clock(task_runner->GetMockTickClock());
-  MessageLoop message_loop;
-  message_loop.SetTaskRunner(task_runner);
-  Receiver receiver;
-  RepeatingTimer timer(tick_clock.get());
-  timer.Start(FROM_HERE, TimeDelta::FromSeconds(2),
-              Bind(&Receiver::OnCalled, Unretained(&receiver)));
-  EXPECT_EQ(TimeDelta::FromSeconds(2), timer.GetTimeToCallback());
-  task_runner->FastForwardBy(TimeDelta::FromSeconds(1));
-  EXPECT_EQ(TimeDelta::FromSeconds(1), timer.GetTimeToCallback());
-  task_runner->FastForwardBy(TimeDelta::FromSeconds(1));
-  EXPECT_EQ(TimeDelta::FromSeconds(2), timer.GetTimeToCallback());
-}
-
 namespace {
 
 bool g_callback_happened1 = false;
diff --git a/build/linux/sysroot_scripts/packagelist.jessie.amd64 b/build/linux/sysroot_scripts/packagelist.jessie.amd64
index 0fb7cc3..9390b4d1 100644
--- a/build/linux/sysroot_scripts/packagelist.jessie.amd64
+++ b/build/linux/sysroot_scripts/packagelist.jessie.amd64
@@ -93,6 +93,8 @@
 main/libg/libgnome-keyring/libgnome-keyring-dev_3.12.0-1+b1_amd64.deb
 main/libg/libgpg-error/libgpg-error0_1.17-3_amd64.deb
 main/libg/libgpg-error/libgpg-error-dev_1.17-3_amd64.deb
+main/libj/libjsoncpp/libjsoncpp0_0.6.0~rc2-3.1_amd64.deb
+main/libj/libjsoncpp/libjsoncpp-dev_0.6.0~rc2-3.1_amd64.deb
 main/libn/libnss-db/libnss-db_2.2.3pre1-5+b3_amd64.deb
 main/libp/libp11/libp11-2_0.2.8-5_amd64.deb
 main/libp/libpng/libpng12-0_1.2.50-2+deb8u2_amd64.deb
diff --git a/build/linux/sysroot_scripts/packagelist.jessie.arm b/build/linux/sysroot_scripts/packagelist.jessie.arm
index a6db5525..e16b942 100644
--- a/build/linux/sysroot_scripts/packagelist.jessie.arm
+++ b/build/linux/sysroot_scripts/packagelist.jessie.arm
@@ -90,6 +90,8 @@
 main/libg/libgnome-keyring/libgnome-keyring-dev_3.12.0-1+b1_armhf.deb
 main/libg/libgpg-error/libgpg-error0_1.17-3_armhf.deb
 main/libg/libgpg-error/libgpg-error-dev_1.17-3_armhf.deb
+main/libj/libjsoncpp/libjsoncpp0_0.6.0~rc2-3.1_armhf.deb
+main/libj/libjsoncpp/libjsoncpp-dev_0.6.0~rc2-3.1_armhf.deb
 main/libn/libnss-db/libnss-db_2.2.3pre1-5+b3_armhf.deb
 main/libp/libp11/libp11-2_0.2.8-5_armhf.deb
 main/libp/libpng/libpng12-0_1.2.50-2+deb8u2_armhf.deb
diff --git a/build/linux/sysroot_scripts/packagelist.jessie.arm64 b/build/linux/sysroot_scripts/packagelist.jessie.arm64
index 5fcd638..f120f652 100644
--- a/build/linux/sysroot_scripts/packagelist.jessie.arm64
+++ b/build/linux/sysroot_scripts/packagelist.jessie.arm64
@@ -89,6 +89,8 @@
 main/libg/libgnome-keyring/libgnome-keyring-dev_3.12.0-1+b1_arm64.deb
 main/libg/libgpg-error/libgpg-error0_1.17-3_arm64.deb
 main/libg/libgpg-error/libgpg-error-dev_1.17-3_arm64.deb
+main/libj/libjsoncpp/libjsoncpp0_0.6.0~rc2-3.1_arm64.deb
+main/libj/libjsoncpp/libjsoncpp-dev_0.6.0~rc2-3.1_arm64.deb
 main/libn/libnss-db/libnss-db_2.2.3pre1-5_arm64.deb
 main/libp/libp11/libp11-2_0.2.8-5_arm64.deb
 main/libp/libpng/libpng12-0_1.2.50-2+deb8u2_arm64.deb
diff --git a/build/linux/sysroot_scripts/packagelist.jessie.i386 b/build/linux/sysroot_scripts/packagelist.jessie.i386
index 61c8bb98..01001c0 100644
--- a/build/linux/sysroot_scripts/packagelist.jessie.i386
+++ b/build/linux/sysroot_scripts/packagelist.jessie.i386
@@ -91,6 +91,8 @@
 main/libg/libgnome-keyring/libgnome-keyring-dev_3.12.0-1+b1_i386.deb
 main/libg/libgpg-error/libgpg-error0_1.17-3_i386.deb
 main/libg/libgpg-error/libgpg-error-dev_1.17-3_i386.deb
+main/libj/libjsoncpp/libjsoncpp0_0.6.0~rc2-3.1_i386.deb
+main/libj/libjsoncpp/libjsoncpp-dev_0.6.0~rc2-3.1_i386.deb
 main/libn/libnss-db/libnss-db_2.2.3pre1-5+b3_i386.deb
 main/libp/libp11/libp11-2_0.2.8-5_i386.deb
 main/libp/libpng/libpng12-0_1.2.50-2+deb8u2_i386.deb
diff --git a/build/linux/sysroot_scripts/packagelist.jessie.mipsel b/build/linux/sysroot_scripts/packagelist.jessie.mipsel
index acee15d4..c19c960 100644
--- a/build/linux/sysroot_scripts/packagelist.jessie.mipsel
+++ b/build/linux/sysroot_scripts/packagelist.jessie.mipsel
@@ -85,6 +85,8 @@
 main/libg/libgnome-keyring/libgnome-keyring-dev_3.12.0-1+b1_mipsel.deb
 main/libg/libgpg-error/libgpg-error0_1.17-3_mipsel.deb
 main/libg/libgpg-error/libgpg-error-dev_1.17-3_mipsel.deb
+main/libj/libjsoncpp/libjsoncpp0_0.6.0~rc2-3.1_mipsel.deb
+main/libj/libjsoncpp/libjsoncpp-dev_0.6.0~rc2-3.1_mipsel.deb
 main/libn/libnss-db/libnss-db_2.2.3pre1-5+b3_mipsel.deb
 main/libp/libp11/libp11-2_0.2.8-5_mipsel.deb
 main/libp/libpng/libpng12-0_1.2.50-2+deb8u2_mipsel.deb
diff --git a/build/linux/sysroot_scripts/sysroot-creator-jessie.sh b/build/linux/sysroot_scripts/sysroot-creator-jessie.sh
index 95249c1..5f0f955 100755
--- a/build/linux/sysroot_scripts/sysroot-creator-jessie.sh
+++ b/build/linux/sysroot_scripts/sysroot-creator-jessie.sh
@@ -109,6 +109,8 @@
   libharfbuzz-gobject0
   libharfbuzz-icu0
   libatomic1
+  libjsoncpp0
+  libjsoncpp-dev
   libk5crypto3
   libkadm5clnt-mit9
   libkadm5srv-mit9
diff --git a/build/toolchain/mac/BUILD.gn b/build/toolchain/mac/BUILD.gn
index 211f43b4..537c733e 100644
--- a/build/toolchain/mac/BUILD.gn
+++ b/build/toolchain/mac/BUILD.gn
@@ -83,6 +83,17 @@
       host_toolchain = host_toolchain
     }
 
+    # Supports building with the version of clang shipped with Xcode when
+    # targetting iOS by not respecting clang_base_path.
+    if (toolchain_args.current_os == "ios" && use_xcode_clang) {
+      prefix = ""
+    } else {
+      prefix = rebase_path("$clang_base_path/bin/", root_build_dir)
+    }
+
+    _cc = "${prefix}clang"
+    _cxx = "${prefix}clang++"
+
     # When the invoker has explicitly overridden use_goma or cc_wrapper in the
     # toolchain args, use those values, otherwise default to the global one.
     # This works because the only reasonable override that toolchains might
@@ -109,13 +120,9 @@
       compiler_prefix = ""
     }
 
-    if (toolchain_args.current_os != "ios" || !use_xcode_clang) {
-      compiler_prefix += rebase_path("$clang_base_path/bin/", root_build_dir)
-    }
-
-    cc = "${compiler_prefix}clang"
-    cxx = "${compiler_prefix}clang++"
-    ld = cxx
+    cc = compiler_prefix + _cc
+    cxx = compiler_prefix + _cxx
+    ld = _cxx
 
     linker_driver =
         "TOOL_VERSION=${tool_versions.linker_driver} " +
diff --git a/cc/input/main_thread_scrolling_reason.h b/cc/input/main_thread_scrolling_reason.h
index d06cbd18..3fddc43 100644
--- a/cc/input/main_thread_scrolling_reason.h
+++ b/cc/input/main_thread_scrolling_reason.h
@@ -48,12 +48,11 @@
     kNonInvertibleTransform = 1 << 11,
     kPageBasedScrolling = 1 << 12,
 
-    // TODO(yigu): the following variable is confusing. It's not the count of
-    // values, but the maximum shift + 2 because the loop in
-    // InputHandlerProxy::RecordMainThreadScrollingReasons is "wrong".
-    // It should be the max number of flags in this struct (excluding itself).
-    // Will fix it in a followup patch.
-    kMainThreadScrollingReasonCount = 22,
+    // The maximum number of flags in this struct (excluding itself).
+    // New flags should increment this number but it should never be decremented
+    // because the values are used in UMA histograms. It should also be noted
+    // that it excludes the kNotScrollingOnMain value.
+    kMainThreadScrollingReasonCount = 21,
   };
 
   // Returns true if the given MainThreadScrollingReason can be set by the main
@@ -144,7 +143,7 @@
     if (reason & (reason - 1))
       return -1;
 
-    int index = 0;
+    int index = -1;
     while (reason > 0) {
       reason = reason >> 1;
       ++index;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
index 1431d7dd..155ee312 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -1202,7 +1202,7 @@
                 currentTab.loadUrl(new LoadUrlParams(
                         UrlConstants.RECENT_TABS_URL,
                         PageTransition.AUTO_BOOKMARK));
-                RecordUserAction.record("MobileMenuOpenTabs");
+                RecordUserAction.record("MobileMenuRecentTabs");
             }
         } else if (id == R.id.close_all_tabs_menu_id) {
             // Close both incognito and normal tabs
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ShortcutHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/ShortcutHelper.java
index 6231df55..9bb16677 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ShortcutHelper.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ShortcutHelper.java
@@ -219,11 +219,27 @@
      * Show toast to alert user that the shortcut was added to the home screen.
      */
     private static void showAddedToHomescreenToast(final String title) {
-        assert ThreadUtils.runningOnUiThread();
-
         Context applicationContext = ContextUtils.getApplicationContext();
         String toastText = applicationContext.getString(R.string.added_to_homescreen, title);
-        Toast toast = Toast.makeText(applicationContext, toastText, Toast.LENGTH_SHORT);
+        showToast(toastText);
+    }
+
+    /**
+     * Shows toast notifying user that a WebAPK install is already in progress when user tries to
+     * queue a new install for the same WebAPK.
+     */
+    @SuppressWarnings("unused")
+    @CalledByNative
+    private static void showWebApkInstallInProgressToast() {
+        Context applicationContext = ContextUtils.getApplicationContext();
+        String toastText = applicationContext.getString(R.string.webapk_install_in_progress);
+        showToast(toastText);
+    }
+
+    private static void showToast(String text) {
+        assert ThreadUtils.runningOnUiThread();
+        Toast toast =
+                Toast.makeText(ContextUtils.getApplicationContext(), text, Toast.LENGTH_SHORT);
         toast.show();
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryAdapter.java
index 10862e3c..397b30b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryAdapter.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryAdapter.java
@@ -14,6 +14,7 @@
 import android.widget.TextView;
 
 import org.chromium.base.ContextUtils;
+import org.chromium.base.VisibleForTesting;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.history.HistoryProvider.BrowsingHistoryObserver;
 import org.chromium.chrome.browser.widget.DateDividedAdapter;
@@ -275,4 +276,19 @@
         mOtherFormsOfBrowsingHistoryTextView.setVisibility(
                 mHasOtherFormsOfBrowsingData ? View.VISIBLE : View.GONE);
     }
+
+    @VisibleForTesting
+    TextView getSignedInNotSyncedViewForTests() {
+        return mSignedInNotSyncedTextView;
+    }
+
+    @VisibleForTesting
+    TextView getSignedInSyncedViewForTests() {
+        return mSignedInSyncedTextView;
+    }
+
+    @VisibleForTesting
+    TextView getOtherFormsOfBrowsingHistoryViewForTests() {
+        return mOtherFormsOfBrowsingHistoryTextView;
+    }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManager.java b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManager.java
index 45f07f89..c94b4b600 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManager.java
@@ -181,10 +181,17 @@
      *                     the current tab.
      */
     public void openUrl(String url, Boolean isIncognito, boolean createNewTab) {
+        IntentHandler.startActivityForTrustedIntent(
+                getOpenUrlIntent(url, isIncognito, createNewTab));
+    }
+
+    @VisibleForTesting
+    Intent getOpenUrlIntent(String url, Boolean isIncognito, boolean createNewTab) {
         // Construct basic intent.
         Intent viewIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
         viewIntent.putExtra(Browser.EXTRA_APPLICATION_ID,
                 mActivity.getApplicationContext().getPackageName());
+        viewIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
 
         // Determine component or class name.
         ComponentName component;
@@ -206,8 +213,7 @@
         }
         if (createNewTab) viewIntent.putExtra(Browser.EXTRA_CREATE_NEW_TAB, true);
 
-        // Send intent.
-        IntentHandler.startActivityForTrustedIntent(viewIntent);
+        return viewIntent;
     }
 
     /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/mojo/ChromeInterfaceRegistrar.java b/chrome/android/java/src/org/chromium/chrome/browser/mojo/ChromeInterfaceRegistrar.java
index ac04f445..21fd517 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/mojo/ChromeInterfaceRegistrar.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/mojo/ChromeInterfaceRegistrar.java
@@ -6,8 +6,10 @@
 
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.blink.mojom.BarcodeDetection;
+import org.chromium.blink.mojom.TextDetection;
 import org.chromium.chrome.browser.payments.PaymentRequestFactory;
 import org.chromium.chrome.browser.shapedetection.BarcodeDetectionFactory;
+import org.chromium.chrome.browser.shapedetection.TextDetectionFactory;
 import org.chromium.chrome.browser.webshare.ShareServiceImplementationFactory;
 import org.chromium.content_public.browser.InterfaceRegistrar;
 import org.chromium.content_public.browser.WebContents;
@@ -32,5 +34,6 @@
                 ShareService.MANAGER, new ShareServiceImplementationFactory(webContents));
         registry.addInterface(
                 BarcodeDetection.MANAGER, new BarcodeDetectionFactory(webContents));
+        registry.addInterface(TextDetection.MANAGER, new TextDetectionFactory(webContents));
     }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/AutofillPaymentApp.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/AutofillPaymentApp.java
index eff6aac..f4dad75 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/payments/AutofillPaymentApp.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/AutofillPaymentApp.java
@@ -12,9 +12,12 @@
 import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile;
 import org.chromium.chrome.browser.autofill.PersonalDataManager.CreditCard;
 import org.chromium.content_public.browser.WebContents;
+import org.chromium.payments.mojom.BasicCardNetwork;
+import org.chromium.payments.mojom.BasicCardType;
 import org.chromium.payments.mojom.PaymentMethodData;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
@@ -24,6 +27,9 @@
  * Provides access to locally stored user credit cards.
  */
 public class AutofillPaymentApp implements PaymentApp {
+    /** The method name for any type of credit card. */
+    public static final String BASIC_CARD_METHOD_NAME = "basic-card";
+
     private final Context mContext;
     private final WebContents mWebContents;
 
@@ -39,12 +45,15 @@
     }
 
     @Override
-    public void getInstruments(Map<String, PaymentMethodData> unusedMethodDataMap,
-            String unusedOrigin, final InstrumentsCallback callback) {
+    public void getInstruments(Map<String, PaymentMethodData> methodDataMap, String unusedOrigin,
+            final InstrumentsCallback callback) {
         PersonalDataManager pdm = PersonalDataManager.getInstance();
         List<CreditCard> cards = pdm.getCreditCardsToSuggest();
         final List<PaymentInstrument> instruments = new ArrayList<>(cards.size());
 
+        Set<String> basicCardSupportedNetworks =
+                convertBasicCardToNetworks(methodDataMap.get(BASIC_CARD_METHOD_NAME));
+
         for (int i = 0; i < cards.size(); i++) {
             CreditCard card = cards.get(i);
             AutofillProfile billingAddress = TextUtils.isEmpty(card.getBillingAddressId())
@@ -56,8 +65,18 @@
                 billingAddress = null;
             }
 
-            instruments.add(new AutofillPaymentInstrument(mContext, mWebContents, card,
-                    billingAddress));
+            String methodName = null;
+            if (basicCardSupportedNetworks != null
+                    && basicCardSupportedNetworks.contains(card.getBasicCardPaymentType())) {
+                methodName = BASIC_CARD_METHOD_NAME;
+            } else if (methodDataMap.containsKey(card.getBasicCardPaymentType())) {
+                methodName = card.getBasicCardPaymentType();
+            }
+
+            if (methodName != null) {
+                instruments.add(new AutofillPaymentInstrument(mContext, mWebContents, card,
+                        billingAddress, methodName));
+            }
         }
 
         new Handler().post(new Runnable() {
@@ -68,35 +87,77 @@
         });
     }
 
+    /** @return A set of card networks (e.g., "visa", "amex") accepted by "basic-card" method. */
+    public static Set<String> convertBasicCardToNetworks(PaymentMethodData data) {
+        // No basic card support.
+        if (data == null) return null;
+
+        boolean supportedTypesEmpty =
+                data.supportedTypes == null || data.supportedTypes.length == 0;
+        boolean supportedNetworksEmpty =
+                data.supportedNetworks == null || data.supportedNetworks.length == 0;
+
+        // All basic cards are supported.
+        Map<Integer, String> networks = getNetworks();
+        if (supportedTypesEmpty && supportedNetworksEmpty) return new HashSet<>(networks.values());
+
+        // https://w3c.github.io/webpayments-methods-card/#basiccardrequest defines 3 types of
+        // cards: "credit", "debit", and "prepaid". Specifying a non-empty subset of these types
+        // requires filtering by type, which Chrome cannot yet do.
+        // TODO(rouslan): Distinguish card types. http://crbug.com/602665
+        if (!supportedTypesEmpty) {
+            if (data.supportedTypes.length != 3) return null;
+            Set<Integer> supportedTypes = new HashSet<>();
+            for (int i = 0; i < data.supportedTypes.length; i++) {
+                supportedTypes.add(data.supportedTypes[i]);
+            }
+            if (!supportedTypes.contains(BasicCardType.CREDIT)) return null;
+            if (!supportedTypes.contains(BasicCardType.DEBIT)) return null;
+            if (!supportedTypes.contains(BasicCardType.PREPAID)) return null;
+        }
+
+        // All basic cards are supported.
+        if (supportedNetworksEmpty) return new HashSet<>(networks.values());
+
+        Set<String> result = new HashSet<>();
+        for (int i = 0; i < data.supportedNetworks.length; i++) {
+            String network = networks.get(data.supportedNetworks[i]);
+            if (network != null) result.add(network);
+        }
+        return result;
+    }
+
+    private static Map<Integer, String> getNetworks() {
+        Map<Integer, String> networks = new HashMap<>();
+        networks.put(BasicCardNetwork.AMEX, "amex");
+        networks.put(BasicCardNetwork.DINERS, "diners");
+        networks.put(BasicCardNetwork.DISCOVER, "discover");
+        networks.put(BasicCardNetwork.JCB, "jcb");
+        networks.put(BasicCardNetwork.MASTERCARD, "mastercard");
+        networks.put(BasicCardNetwork.UNIONPAY, "unionpay");
+        networks.put(BasicCardNetwork.VISA, "visa");
+        return networks;
+    }
+
     @Override
     public Set<String> getAppMethodNames() {
-        // https://w3c.github.io/webpayments-methods-card/#method-id
-        // The spec also includes more detailed card types, e.g., "visa/credit" and "visa/debit".
-        // Autofill does not distinguish between these types of cards, so they are not in the list
-        // of supported method names.
-        Set<String> methods = new HashSet<>();
-
-        methods.add("visa");
-        methods.add("mastercard");
-        methods.add("amex");
-        methods.add("discover");
-        methods.add("diners");
-        methods.add("jcb");
-        methods.add("unionpay");
-        methods.add("mir");
-
-        // The spec does not include "generic" card types. That's the type of card for which
-        // Chrome cannot determine the type.
-        methods.add("generic");
-
+        Set<String> methods = new HashSet<>(getNetworks().values());
+        methods.add(BASIC_CARD_METHOD_NAME);
         return methods;
     }
 
     @Override
     public boolean supportsMethodsAndData(Map<String, PaymentMethodData> methodDataMap) {
         assert methodDataMap != null;
+
+        PaymentMethodData basicCardData = methodDataMap.get(BASIC_CARD_METHOD_NAME);
+        if (basicCardData != null) {
+            Set<String> basicCardNetworks = convertBasicCardToNetworks(basicCardData);
+            if (basicCardNetworks != null && !basicCardNetworks.isEmpty()) return true;
+        }
+
         Set<String> methodNames = new HashSet<>(methodDataMap.keySet());
-        methodNames.retainAll(getAppMethodNames());
+        methodNames.retainAll(getNetworks().values());
         return !methodNames.isEmpty();
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/AutofillPaymentInstrument.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/AutofillPaymentInstrument.java
index 406ff9fc7..1e6d3bd 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/payments/AutofillPaymentInstrument.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/AutofillPaymentInstrument.java
@@ -39,6 +39,7 @@
     private CreditCard mCard;
     private String mSecurityCode;
     @Nullable private AutofillProfile mBillingAddress;
+    @Nullable private String mMethodName;
     @Nullable private InstrumentDetailsCallback mCallback;
     private boolean mIsWaitingForBillingNormalization;
     private boolean mIsWaitingForFullCardDetails;
@@ -51,9 +52,10 @@
      * @param webContents    The web contents where PaymentRequest was invoked.
      * @param card           The autofill card that can be used for payment.
      * @param billingAddress The billing address for the card.
+     * @param methodName     The payment method name, e.g., "basic-card", "visa", amex", or null.
      */
     public AutofillPaymentInstrument(Context context, WebContents webContents, CreditCard card,
-            @Nullable AutofillProfile billingAddress) {
+            @Nullable AutofillProfile billingAddress, @Nullable String methodName) {
         super(card.getGUID(), card.getObfuscatedNumber(), card.getName(),
                 card.getIssuerIconDrawableId() == 0
                 ? null
@@ -64,13 +66,14 @@
         mCard = card;
         mBillingAddress = billingAddress;
         mIsEditable = true;
+        mMethodName = methodName;
         checkAndUpateCardCompleteness();
     }
 
     @Override
     public Set<String> getInstrumentMethodNames() {
         Set<String> result = new HashSet<>();
-        result.add(mCard.getBasicCardPaymentType());
+        result.add(mMethodName);
         return result;
     }
 
@@ -197,8 +200,7 @@
             mSecurityCode = "";
         }
 
-        mCallback.onInstrumentDetailsReady(
-                mCard.getBasicCardPaymentType(), stringWriter.toString());
+        mCallback.onInstrumentDetailsReady(mMethodName, stringWriter.toString());
     }
 
     private static String ensureNotNull(@Nullable String value) {
@@ -235,11 +237,15 @@
      * instrument.
      *
      * @param card           The new credit card to use. The GUID should not change.
+     * @param methodName     The payment method name to use for this instrument, e.g., "visa",
+     *                       "basic-card".
      * @param billingAddress The billing address for the card. The GUID should match the billing
      *                       address ID of the new card to use.
      */
-    public void completeInstrument(CreditCard card, AutofillProfile billingAddress) {
+    public void completeInstrument(
+            CreditCard card, String methodName, AutofillProfile billingAddress) {
         assert card != null;
+        assert methodName != null;
         assert billingAddress != null;
         assert card.getBillingAddressId() != null;
         assert card.getBillingAddressId().equals(billingAddress.getGUID());
@@ -248,6 +254,7 @@
                 == AutofillAddress.COMPLETE;
 
         mCard = card;
+        mMethodName = methodName;
         mBillingAddress = billingAddress;
         updateIdentifierLabelsAndIcon(card.getGUID(), card.getObfuscatedNumber(), card.getName(),
                 null, ApiCompatibilityUtils.getDrawable(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/CardEditor.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/CardEditor.java
index 9ab773d..7a312f9 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/payments/CardEditor.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/CardEditor.java
@@ -22,6 +22,7 @@
 import org.chromium.chrome.browser.payments.ui.EditorModel;
 import org.chromium.chrome.browser.preferences.autofill.AutofillProfileBridge.DropdownKeyValue;
 import org.chromium.content_public.browser.WebContents;
+import org.chromium.payments.mojom.PaymentMethodData;
 
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
@@ -112,6 +113,13 @@
     private final Set<String> mAcceptedCardTypes;
 
     /**
+     * The card types accepted by the merchant website that should have "basic-card" as the payment
+     * method. This is a subset of the accepted card types. Used when creating the complete payment
+     * instrument.
+     */
+    private final Set<String> mAcceptedBasicCardTypes;
+
+    /**
      * The information about the accepted card types. Used in the editor as a hint to the user about
      * the valid card types. This is important to keep in a list, because the display order matters.
      */
@@ -184,6 +192,7 @@
         mCardTypes.put(VISA, new CardTypeInfo(R.drawable.pr_visa, R.string.autofill_cc_visa));
 
         mAcceptedCardTypes = new HashSet<>();
+        mAcceptedBasicCardTypes = new HashSet<>();
         mAcceptedCardTypeInfos = new ArrayList<>();
         mHandler = new Handler();
 
@@ -252,21 +261,40 @@
     /**
      * Adds accepted payment methods to the editor, if they are recognized credit card types.
      *
-     * @param acceptedMethods The accepted method payments.
+     * @param data Supported methods and method specific data. Should not be null.
      */
-    public void addAcceptedPaymentMethodsIfRecognized(String[] acceptedMethods) {
-        assert acceptedMethods != null;
-        for (int i = 0; i < acceptedMethods.length; i++) {
-            String method = acceptedMethods[i];
+    public void addAcceptedPaymentMethodsIfRecognized(PaymentMethodData data) {
+        assert data != null;
+        for (int i = 0; i < data.supportedMethods.length; i++) {
+            String method = data.supportedMethods[i];
             if (mCardTypes.containsKey(method)) {
-                assert !mAcceptedCardTypes.contains(method);
-                mAcceptedCardTypes.add(method);
-                mAcceptedCardTypeInfos.add(mCardTypes.get(method));
+                addAcceptedNetwork(method);
+            } else if (AutofillPaymentApp.BASIC_CARD_METHOD_NAME.equals(method)) {
+                Set<String> basicCardNetworks = AutofillPaymentApp.convertBasicCardToNetworks(data);
+                if (basicCardNetworks != null) {
+                    mAcceptedBasicCardTypes.addAll(basicCardNetworks);
+                    for (String network : basicCardNetworks) {
+                        addAcceptedNetwork(network);
+                    }
+                }
             }
         }
     }
 
     /**
+     * Adds a card network to the list of accepted networks.
+     *
+     * @param network An accepted network. Will be shown in UI only once, regardless of how many
+     *                times this method is called.
+     */
+    private void addAcceptedNetwork(String network) {
+        if (!mAcceptedCardTypes.contains(network)) {
+            mAcceptedCardTypes.add(network);
+            mAcceptedCardTypeInfos.add(mCardTypes.get(network));
+        }
+    }
+
+    /**
      * Builds and shows an editor model with the following fields for local cards.
      *
      * [ accepted card types hint images     ]
@@ -291,7 +319,8 @@
 
         // Ensure that |instrument| and |card| are never null.
         final AutofillPaymentInstrument instrument = isNewCard
-                ? new AutofillPaymentInstrument(mContext, mWebContents, new CreditCard(), null)
+                ? new AutofillPaymentInstrument(mContext, mWebContents, new CreditCard(),
+                          null /* billingAddress */, null /* methodName */)
                 : toEdit;
         final CreditCard card = instrument.getCard();
 
@@ -344,13 +373,24 @@
             @Override
             public void run() {
                 commitChanges(card, isNewCard);
+
+                String methodName = card.getBasicCardPaymentType();
+                if (mAcceptedBasicCardTypes.contains(methodName)) {
+                    methodName = AutofillPaymentApp.BASIC_CARD_METHOD_NAME;
+                }
+                assert methodName != null;
+
+                AutofillProfile billingAddress = null;
                 for (int i = 0; i < mProfilesForBillingAddress.size(); ++i) {
                     if (TextUtils.equals(mProfilesForBillingAddress.get(i).getGUID(),
                             card.getBillingAddressId())) {
-                        instrument.completeInstrument(card, mProfilesForBillingAddress.get(i));
+                        billingAddress = mProfilesForBillingAddress.get(i);
                         break;
                     }
                 }
+                assert billingAddress != null;
+
+                instrument.completeInstrument(card, methodName, billingAddress);
                 callback.onResult(instrument);
             }
         });
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentApp.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentApp.java
index 76fc704..b7cf365 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentApp.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentApp.java
@@ -44,8 +44,8 @@
 
     /**
      * Returns a list of all payment method names that this app supports. For example, ["visa",
-     * "mastercard"] in basic card payments. Should return a list of at least one method name.
-     * https://w3c.github.io/webpayments-methods-card/#method-id
+     * "mastercard", "basic-card"] in basic card payments. Should return a list of at least one
+     * method name. https://w3c.github.io/webpayments-methods-card/#method-id
      *
      * @return The list of all payment method names that this app supports.
      */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java
index dbe3313..1424d7d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java
@@ -562,8 +562,9 @@
                 result.put(methods[j], methodData[i]);
             }
 
-            paymentMethodsCollector.addAcceptedPaymentMethodsIfRecognized(methods);
+            paymentMethodsCollector.addAcceptedPaymentMethodsIfRecognized(methodData[i]);
         }
+
         return Collections.unmodifiableMap(result);
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/shapedetection/TextDetectionFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/shapedetection/TextDetectionFactory.java
new file mode 100644
index 0000000..ff32480b
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/shapedetection/TextDetectionFactory.java
@@ -0,0 +1,40 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.shapedetection;
+
+import android.app.Activity;
+
+import org.chromium.blink.mojom.TextDetection;
+import org.chromium.content.browser.ContentViewCore;
+import org.chromium.content_public.browser.WebContents;
+import org.chromium.services.service_manager.InterfaceFactory;
+import org.chromium.ui.base.WindowAndroid;
+
+/**
+ * Factory class registered to create TextDetections upon request.
+ */
+public class TextDetectionFactory implements InterfaceFactory<TextDetection> {
+    private final WebContents mWebContents;
+
+    public TextDetectionFactory(WebContents webContents) {
+        mWebContents = webContents;
+    }
+
+    @Override
+    public TextDetection createImpl() {
+        // Get android.content.Context out of |mWebContents|.
+
+        final ContentViewCore contentViewCore = ContentViewCore.fromWebContents(mWebContents);
+        if (contentViewCore == null) return null;
+
+        final WindowAndroid window = contentViewCore.getWindowAndroid();
+        if (window == null) return null;
+
+        final Activity context = window.getActivity().get();
+        if (context == null) return null;
+
+        return new TextDetectionImpl(context);
+    }
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/shapedetection/TextDetectionImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/shapedetection/TextDetectionImpl.java
new file mode 100644
index 0000000..01ef6ded
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/shapedetection/TextDetectionImpl.java
@@ -0,0 +1,115 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.shapedetection;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Rect;
+import android.util.SparseArray;
+
+import com.google.android.gms.vision.Frame;
+import com.google.android.gms.vision.text.TextBlock;
+import com.google.android.gms.vision.text.TextRecognizer;
+
+import org.chromium.base.Log;
+import org.chromium.blink.mojom.TextDetection;
+import org.chromium.blink.mojom.TextDetectionResult;
+import org.chromium.chrome.browser.externalauth.ExternalAuthUtils;
+import org.chromium.chrome.browser.externalauth.UserRecoverableErrorHandler;
+import org.chromium.gfx.mojom.RectF;
+import org.chromium.mojo.system.MojoException;
+import org.chromium.mojo.system.SharedBufferHandle;
+import org.chromium.mojo.system.SharedBufferHandle.MapFlags;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Implementation of mojo TextDetection, using Google Play Services vision package.
+ */
+public class TextDetectionImpl implements TextDetection {
+    private static final String TAG = "TextDetectionImpl";
+
+    private final Context mContext;
+    private TextRecognizer mTextRecognizer;
+
+    public TextDetectionImpl(Context context) {
+        mContext = context;
+        mTextRecognizer = new TextRecognizer.Builder(mContext).build();
+    }
+
+    @Override
+    public void detect(
+            SharedBufferHandle frameData, int width, int height, DetectResponse callback) {
+        if (!ExternalAuthUtils.getInstance().canUseGooglePlayServices(
+                    mContext, new UserRecoverableErrorHandler.Silent())) {
+            Log.e(TAG, "Google Play Services not available");
+            callback.call(new TextDetectionResult[0]);
+            return;
+        }
+        // The vision library will be downloaded the first time the API is used
+        // on the device; this happens "fast", but it might have not completed,
+        // bail in this case. Also, the API was disabled between and v.9.0 and
+        // v.9.2, see https://developers.google.com/android/guides/releases.
+        if (!mTextRecognizer.isOperational()) {
+            Log.e(TAG, "TextDetector is not operational");
+            callback.call(new TextDetectionResult[0]);
+            return;
+        }
+
+        final long numPixels = (long) width * height;
+        // TODO(xianglu): https://crbug.com/670028 homogeneize overflow checking.
+        if (!frameData.isValid() || width <= 0 || height <= 0 || numPixels > (Long.MAX_VALUE / 4)) {
+            callback.call(new TextDetectionResult[0]);
+            return;
+        }
+
+        // Mapping |frameData| will fail if the intended mapped size is larger
+        // than its actual capacity, which is limited by the appropriate
+        // mojo::edk::Configuration entry.
+        ByteBuffer imageBuffer = frameData.map(0, numPixels * 4, MapFlags.none());
+        if (imageBuffer.capacity() <= 0) {
+            callback.call(new TextDetectionResult[0]);
+            return;
+        }
+
+        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+        bitmap.copyPixelsFromBuffer(imageBuffer);
+
+        Frame frame = null;
+        try {
+            // This constructor implies a pixel format conversion to YUV.
+            frame = new Frame.Builder().setBitmap(bitmap).build();
+        } catch (IllegalArgumentException | IllegalStateException ex) {
+            Log.e(TAG, "Frame.Builder().setBitmap() or build(): " + ex);
+            callback.call(new TextDetectionResult[0]);
+            return;
+        }
+
+        final SparseArray<TextBlock> textBlocks = mTextRecognizer.detect(frame);
+
+        TextDetectionResult[] detectedTextArray = new TextDetectionResult[textBlocks.size()];
+        for (int i = 0; i < textBlocks.size(); i++) {
+            detectedTextArray[i] = new TextDetectionResult();
+            detectedTextArray[i].rawValue = textBlocks.valueAt(i).getValue();
+            final Rect rect = textBlocks.valueAt(i).getBoundingBox();
+            detectedTextArray[i].boundingBox = new RectF();
+            detectedTextArray[i].boundingBox.x = rect.left;
+            detectedTextArray[i].boundingBox.y = rect.top;
+            detectedTextArray[i].boundingBox.width = rect.width();
+            detectedTextArray[i].boundingBox.height = rect.height();
+        }
+        callback.call(detectedTextArray);
+    }
+
+    @Override
+    public void close() {
+        mTextRecognizer.release();
+    }
+
+    @Override
+    public void onConnectionError(MojoException e) {
+        close();
+    }
+}
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd
index b022179b..5b6f3ce 100644
--- a/chrome/android/java/strings/android_chrome_strings.grd
+++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -1574,6 +1574,9 @@
       <message name="IDS_FAIL_TO_INSTALL_WEBAPK" desc="The installation of a WebAPK fails. [CHAR-LIMIT=27]">
         Unable to add
       </message>
+      <message name="IDS_WEBAPK_INSTALL_IN_PROGRESS" desc="Indicates that an installation for the WebAPK for the specific website is already in progress.">
+        Still adding previous site
+      </message>
 
       <!-- WebsiteSettingsPopup (PageInfo dialog) -->
       <message name="IDS_PAGE_INFO_SITE_SETTINGS_BUTTON" desc="Text in the button that opens a website's Site Settings from the Page Info dialog.">
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni
index a071d23a..489847e 100644
--- a/chrome/android/java_sources.gni
+++ b/chrome/android/java_sources.gni
@@ -889,6 +889,8 @@
   "java/src/org/chromium/chrome/browser/sessions/SessionTabHelper.java",
   "java/src/org/chromium/chrome/browser/shapedetection/BarcodeDetectionFactory.java",
   "java/src/org/chromium/chrome/browser/shapedetection/BarcodeDetectionImpl.java",
+  "java/src/org/chromium/chrome/browser/shapedetection/TextDetectionFactory.java",
+  "java/src/org/chromium/chrome/browser/shapedetection/TextDetectionImpl.java",
   "java/src/org/chromium/chrome/browser/share/ShareDialogAdapter.java",
   "java/src/org/chromium/chrome/browser/share/ShareHelper.java",
   "java/src/org/chromium/chrome/browser/signin/AccountAdder.java",
@@ -1347,6 +1349,7 @@
   "javatests/src/org/chromium/chrome/browser/policy/CombinedPolicyProviderTest.java",
   "javatests/src/org/chromium/chrome/browser/payments/CurrencyStringFormatterTest.java",
   "javatests/src/org/chromium/chrome/browser/payments/PaymentRequestAbortTest.java",
+  "javatests/src/org/chromium/chrome/browser/payments/PaymentRequestBasicCardTest.java",
   "javatests/src/org/chromium/chrome/browser/payments/PaymentRequestCanMakePaymentQueryNoCardTest.java",
   "javatests/src/org/chromium/chrome/browser/payments/PaymentRequestCanMakePaymentQueryTest.java",
   "javatests/src/org/chromium/chrome/browser/payments/PaymentRequestBillingAddressTest.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/history/HistoryActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/history/HistoryActivityTest.java
index b555b60af..9a9367e 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/history/HistoryActivityTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/history/HistoryActivityTest.java
@@ -4,8 +4,15 @@
 
 package org.chromium.chrome.browser.history;
 
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.app.Instrumentation.ActivityMonitor;
+import android.content.Intent;
+import android.content.IntentFilter;
 import android.os.Handler;
 import android.os.Looper;
+import android.os.PatternMatcher;
+import android.provider.Browser;
 import android.support.test.filters.SmallTest;
 import android.support.v7.widget.RecyclerView;
 import android.support.v7.widget.RecyclerView.ViewHolder;
@@ -16,11 +23,15 @@
 import org.chromium.base.test.util.CallbackHelper;
 import org.chromium.base.test.util.Restriction;
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.IntentHandler;
 import org.chromium.chrome.browser.widget.TintedImageButton;
 import org.chromium.chrome.browser.widget.selection.SelectableItemView;
 import org.chromium.chrome.browser.widget.selection.SelectableItemViewHolder;
 import org.chromium.chrome.browser.widget.selection.SelectionDelegate.SelectionObserver;
 import org.chromium.chrome.test.util.ChromeRestriction;
+import org.chromium.components.signin.ChromeSigninController;
+import org.chromium.content.browser.test.util.Criteria;
+import org.chromium.content.browser.test.util.CriteriaHelper;
 
 import java.util.Date;
 import java.util.List;
@@ -150,6 +161,138 @@
         assertEquals(View.VISIBLE, mHistoryManager.getEmptyViewForTests().getVisibility());
     }
 
+    @SmallTest
+    public void testPrivacyDisclaimers_SignedOut() {
+        ChromeSigninController signinController = ChromeSigninController.get(getActivity());
+        signinController.setSignedInAccountName(null);
+
+        assertEquals(View.GONE, mAdapter.getSignedInNotSyncedViewForTests().getVisibility());
+        assertEquals(View.GONE, mAdapter.getSignedInSyncedViewForTests().getVisibility());
+        assertEquals(View.GONE,
+                mAdapter.getOtherFormsOfBrowsingHistoryViewForTests().getVisibility());
+    }
+
+    @SmallTest
+    public void testPrivacyDisclaimers_SignedIn() {
+        ChromeSigninController signinController = ChromeSigninController.get(getActivity());
+        signinController.setSignedInAccountName("test@gmail.com");
+
+        setHasOtherFormsOfBrowsingData(false, false);
+
+        assertEquals(View.VISIBLE, mAdapter.getSignedInNotSyncedViewForTests().getVisibility());
+        assertEquals(View.GONE, mAdapter.getSignedInSyncedViewForTests().getVisibility());
+        assertEquals(View.GONE,
+                mAdapter.getOtherFormsOfBrowsingHistoryViewForTests().getVisibility());
+
+        signinController.setSignedInAccountName(null);
+    }
+
+    @SmallTest
+    public void testPrivacyDisclaimers_SignedInSynced() {
+        ChromeSigninController signinController = ChromeSigninController.get(getActivity());
+        signinController.setSignedInAccountName("test@gmail.com");
+
+        setHasOtherFormsOfBrowsingData(false, true);
+
+        assertEquals(View.GONE, mAdapter.getSignedInNotSyncedViewForTests().getVisibility());
+        assertEquals(View.VISIBLE, mAdapter.getSignedInSyncedViewForTests().getVisibility());
+        assertEquals(View.GONE,
+                mAdapter.getOtherFormsOfBrowsingHistoryViewForTests().getVisibility());
+
+        signinController.setSignedInAccountName(null);
+    }
+
+    @SmallTest
+    public void testPrivacyDisclaimers_SignedInSyncedAndOtherForms() {
+        ChromeSigninController signinController = ChromeSigninController.get(getActivity());
+        signinController.setSignedInAccountName("test@gmail.com");
+
+        setHasOtherFormsOfBrowsingData(true, true);
+
+        assertEquals(View.GONE, mAdapter.getSignedInNotSyncedViewForTests().getVisibility());
+        assertEquals(View.VISIBLE, mAdapter.getSignedInSyncedViewForTests().getVisibility());
+        assertEquals(View.VISIBLE,
+                mAdapter.getOtherFormsOfBrowsingHistoryViewForTests().getVisibility());
+
+        signinController.setSignedInAccountName(null);
+    }
+
+    @SmallTest
+    public void testOpenItem() throws Exception {
+        IntentFilter filter = new IntentFilter(Intent.ACTION_VIEW);
+        filter.addDataPath(mItem1.getUrl(), PatternMatcher.PATTERN_LITERAL);
+        final ActivityMonitor activityMonitor = getInstrumentation().addMonitor(
+                filter, new Instrumentation.ActivityResult(Activity.RESULT_OK, null),
+                true);
+
+        clickItem(2);
+
+        CriteriaHelper.pollInstrumentationThread(new Criteria() {
+            @Override
+            public boolean isSatisfied() {
+                return getInstrumentation().checkMonitorHit(activityMonitor, 1);
+            }
+        });
+    }
+
+    @SmallTest
+    public void testOpenSelectedItems() throws Exception {
+        IntentFilter filter = new IntentFilter(Intent.ACTION_VIEW);
+        filter.addDataPath(mItem1.getUrl(), PatternMatcher.PATTERN_LITERAL);
+        filter.addDataPath(mItem2.getUrl(), PatternMatcher.PATTERN_LITERAL);
+        final ActivityMonitor activityMonitor = getInstrumentation().addMonitor(
+                filter, new Instrumentation.ActivityResult(Activity.RESULT_OK, null),
+                true);
+
+        toggleItemSelection(2);
+        toggleItemSelection(3);
+        ThreadUtils.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                assertTrue(mHistoryManager.getToolbarForTests().getMenu()
+                        .performIdentifierAction(R.id.selection_mode_open_in_incognito, 0));
+            }
+        });
+
+        CriteriaHelper.pollInstrumentationThread(new Criteria() {
+            @Override
+            public boolean isSatisfied() {
+                return getInstrumentation().checkMonitorHit(activityMonitor, 2);
+            }
+        });
+    }
+
+    @SmallTest
+    public void testOpenItemIntent() {
+        Intent intent = mHistoryManager.getOpenUrlIntent(mItem1.getUrl(), null, false);
+        assertEquals(mItem1.getUrl(), intent.getDataString());
+        assertFalse(intent.hasExtra(IntentHandler.EXTRA_OPEN_NEW_INCOGNITO_TAB));
+        assertFalse(intent.hasExtra(Browser.EXTRA_CREATE_NEW_TAB));
+
+        intent = mHistoryManager.getOpenUrlIntent(mItem2.getUrl(), true, true);
+        assertEquals(mItem2.getUrl(), intent.getDataString());
+        assertTrue(intent.getBooleanExtra(IntentHandler.EXTRA_OPEN_NEW_INCOGNITO_TAB, false));
+        assertTrue(intent.getBooleanExtra(Browser.EXTRA_CREATE_NEW_TAB, false));
+    }
+
+    @SmallTest
+    public void testOnHistoryDeleted() throws Exception {
+        toggleItemSelection(2);
+
+        mHistoryProvider.removeItem(mItem1);
+
+        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
+            @Override
+            public void run() {
+                mAdapter.onHistoryDeleted();
+            }
+        });
+
+        // The selection should be cleared and the items in the adapter should be reloaded.
+        assertFalse(mHistoryManager.getSelectionDelegateForTests().isSelectionEnabled());
+        assertEquals(3, mAdapter.getItemCount());
+    }
+
     private void toggleItemSelection(int position) throws Exception {
         int callCount = mTestObserver.onSelectionCallback.getCallCount();
         final SelectableItemView<HistoryItem> itemView = getItemView(position);
@@ -162,10 +305,30 @@
         mTestObserver.onSelectionCallback.waitForCallback(callCount, 1);
     }
 
+    private void clickItem(int position) throws Exception {
+        final SelectableItemView<HistoryItem> itemView = getItemView(position);
+        ThreadUtils.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                itemView.performClick();
+            }
+        });
+    }
+
     @SuppressWarnings("unchecked")
     private SelectableItemView<HistoryItem> getItemView(int position) {
         ViewHolder mostRecentHolder = mRecyclerView.findViewHolderForAdapterPosition(position);
         assertTrue(mostRecentHolder instanceof SelectableItemViewHolder);
         return ((SelectableItemViewHolder<HistoryItem>) mostRecentHolder).getItemView();
     }
+
+    private void setHasOtherFormsOfBrowsingData(final boolean hasOtherForms,
+            final boolean hasSyncedResults)  {
+        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
+            @Override
+            public void run() {
+                mAdapter.hasOtherFormsOfBrowsingData(hasOtherForms, hasSyncedResults);
+            }
+        });
+    }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/history/HistoryAdapterTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/history/HistoryAdapterTest.java
index 1f773ce..e2b780e 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/history/HistoryAdapterTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/history/HistoryAdapterTest.java
@@ -127,6 +127,95 @@
         assertEquals(1, mHistoryProvider.removeItemsCallback.getCallCount());
     }
 
+    @SmallTest
+    public void testSearch() {
+        Date today = new Date();
+        long[] timestamps = {today.getTime()};
+        HistoryItem item1 = StubbedHistoryProvider.createHistoryItem(0, timestamps);
+        mHistoryProvider.addItem(item1);
+
+        long[] timestamps2 = {today.getTime() - TimeUnit.DAYS.toMillis(3)};
+        HistoryItem item2 = StubbedHistoryProvider.createHistoryItem(1, timestamps2);
+        mHistoryProvider.addItem(item2);
+
+        initializeAdapter();
+        checkAdapterContents(true, null, null, item1, null, item2);
+
+        mAdapter.search("google");
+
+        // The header should be hidden during the search.
+        checkAdapterContents(false, null, item1);
+
+        mAdapter.onEndSearch();
+
+        // The header should be shown again after the search.
+        checkAdapterContents(true, null, null, item1, null, item2);
+    }
+
+    @SmallTest
+    public void testLoadMoreItems() {
+        Date today = new Date();
+        long[] timestamps = {today.getTime()};
+        HistoryItem item1 = StubbedHistoryProvider.createHistoryItem(0, timestamps);
+        mHistoryProvider.addItem(item1);
+
+        HistoryItem item2 = StubbedHistoryProvider.createHistoryItem(1, timestamps);
+        mHistoryProvider.addItem(item2);
+
+        HistoryItem item3 = StubbedHistoryProvider.createHistoryItem(2, timestamps);
+        mHistoryProvider.addItem(item3);
+
+        HistoryItem item4 = StubbedHistoryProvider.createHistoryItem(3, timestamps);
+        mHistoryProvider.addItem(item4);
+
+        long[] timestamps2 = {today.getTime() - TimeUnit.DAYS.toMillis(2)};
+        HistoryItem item5 = StubbedHistoryProvider.createHistoryItem(4, timestamps2);
+        mHistoryProvider.addItem(item5);
+
+        HistoryItem item6 = StubbedHistoryProvider.createHistoryItem(0, timestamps2);
+        mHistoryProvider.addItem(item6);
+
+        long[] timestamps3 = {today.getTime() - TimeUnit.DAYS.toMillis(4)};
+        HistoryItem item7 = StubbedHistoryProvider.createHistoryItem(1, timestamps3);
+        mHistoryProvider.addItem(item7);
+
+        initializeAdapter();
+
+        // Only the first five of the seven items should be loaded.
+        checkAdapterContents(true, null, null, item1, item2, item3, item4, null, item5);
+        assertTrue(mAdapter.canLoadMoreItems());
+
+        mAdapter.loadMoreItems();
+
+        // All items should now be loaded.
+        checkAdapterContents(true, null, null, item1, item2, item3, item4, null, item5, item6,
+                null, item7);
+        assertFalse(mAdapter.canLoadMoreItems());
+    }
+
+    @SmallTest
+    public void testOnHistoryDeleted() throws Exception {
+        Date today = new Date();
+        long[] timestamps = {today.getTime()};
+        HistoryItem item1 = StubbedHistoryProvider.createHistoryItem(0, timestamps);
+        mHistoryProvider.addItem(item1);
+
+        initializeAdapter();
+
+        checkAdapterContents(true, null, null, item1);
+
+        mHistoryProvider.removeItem(item1);
+
+        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
+            @Override
+            public void run() {
+                mAdapter.onHistoryDeleted();
+            }
+        });
+
+        checkAdapterContents(false);
+    }
+
     private void checkAdapterContents(boolean hasHeader, Object... expectedItems) {
         assertEquals(expectedItems.length, mAdapter.getItemCount());
         assertEquals(hasHeader, mAdapter.hasListHeader());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/history/StubbedHistoryProvider.java b/chrome/android/javatests/src/org/chromium/chrome/browser/history/StubbedHistoryProvider.java
index 84091e7..bd22f6b7 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/history/StubbedHistoryProvider.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/history/StubbedHistoryProvider.java
@@ -4,10 +4,13 @@
 
 package org.chromium.chrome.browser.history;
 
+import android.text.TextUtils;
+
 import org.chromium.base.test.util.CallbackHelper;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Locale;
 
 /**
  * Stubs out the backends used by the native Android browsing history manager.
@@ -20,6 +23,10 @@
     private List<HistoryItem> mItems = new ArrayList<>();
     private List<HistoryItem> mRemovedItems = new ArrayList<>();
 
+    /** The exclusive end position for the last query. **/
+    private int mLastQueryEndPosition;
+    private String mLastQuery;
+
     @Override
     public void setObserver(BrowsingHistoryObserver observer) {
         mObserver = observer;
@@ -27,7 +34,43 @@
 
     @Override
     public void queryHistory(String query, long endQueryTime) {
-        mObserver.onQueryHistoryComplete(mItems, false);
+        // endQueryTime should be 0 if the query is changing.
+        if (!TextUtils.equals(query, mLastQuery)) assert endQueryTime == 0;
+
+        if (endQueryTime == 0) {
+            mLastQueryEndPosition = 0;
+        } else {
+            // If endQueryTime is not 0, more items are being paged in and endQueryTime should
+            // equal the timestamp of the last HistoryItem returned in the previous query.
+            assert endQueryTime == mItems.get(mLastQueryEndPosition - 1).getTimestamp();
+        }
+
+        // Simulate basic paging to facilitate testing loading more items.
+        // TODO(twellington): support loading more items while searching.
+        int queryStartPosition = mLastQueryEndPosition;
+        int queryStartPositionPlusFive = mLastQueryEndPosition + 5;
+        boolean hasMoreItems = queryStartPositionPlusFive < mItems.size()
+                && TextUtils.isEmpty(query);
+        int queryEndPosition = hasMoreItems ? queryStartPositionPlusFive : mItems.size();
+
+        mLastQueryEndPosition = queryEndPosition;
+        mLastQuery = query;
+
+        List<HistoryItem> items = new ArrayList<>();
+        if (TextUtils.isEmpty(query)) {
+            items = mItems.subList(queryStartPosition, queryEndPosition);
+        } else {
+            // Simulate basic search.
+            query = query.toLowerCase(Locale.getDefault());
+            for (HistoryItem item : mItems) {
+                if (item.getUrl().toLowerCase(Locale.getDefault()).contains(query)
+                        || item.getTitle().toLowerCase(Locale.getDefault()).contains(query)) {
+                    items.add(item);
+                }
+            }
+        }
+
+        mObserver.onQueryHistoryComplete(items, hasMoreItems);
     }
 
     @Override
@@ -52,11 +95,21 @@
         mItems.add(item);
     }
 
+    public void removeItem(HistoryItem item) {
+        mItems.remove(item);
+    }
+
     public static HistoryItem createHistoryItem(int which, long[] timestamps) {
         if (which == 0) {
             return new HistoryItem("http://google.com/", "www.google.com", "Google", timestamps);
         } else if (which == 1) {
             return new HistoryItem("http://foo.com/", "www.foo.com", "Foo", timestamps);
+        } else if (which == 2) {
+            return new HistoryItem("http://bar.com/", "www.bar.com", "Bar", timestamps);
+        } else if (which == 3) {
+            return new HistoryItem("http://news.com/", "www.news.com", "News", timestamps);
+        } else if (which == 4) {
+            return new HistoryItem("http://eng.com/", "www.eng.com", "Engineering", timestamps);
         } else {
             return null;
         }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestBasicCardTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestBasicCardTest.java
new file mode 100644
index 0000000..9c8d03ff
--- /dev/null
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestBasicCardTest.java
@@ -0,0 +1,166 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.payments;
+
+import android.content.DialogInterface;
+import android.support.test.filters.MediumTest;
+
+import org.chromium.base.test.util.CommandLineFlags;
+import org.chromium.base.test.util.Feature;
+import org.chromium.chrome.R;
+import org.chromium.chrome.browser.autofill.AutofillTestHelper;
+import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile;
+import org.chromium.chrome.browser.autofill.PersonalDataManager.CreditCard;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * A payment integration test for "basic-card" payment method.
+ */
+@CommandLineFlags.Add("enable-blink-features=PaymentRequestBasicCard")
+public class PaymentRequestBasicCardTest extends PaymentRequestTestBase {
+    public PaymentRequestBasicCardTest() {
+        super("payment_request_basic_card_test.html");
+    }
+
+    @Override
+    public void onMainActivityStarted() throws InterruptedException, ExecutionException,
+            TimeoutException {
+        // The user has a valid "visa" card.
+        AutofillTestHelper helper = new AutofillTestHelper();
+        String billingAddressId = helper.setProfile(new AutofillProfile("", "https://example.com",
+                true, "Jon Doe", "Google", "340 Main St", "CA", "Los Angeles", "", "90291", "",
+                "US", "555-555-5555", "", "en-US"));
+        helper.setCreditCard(new CreditCard("", "https://example.com", true, true, "Jon Doe",
+                "4111111111111111", "1111", "12", "2050", "visa", R.drawable.pr_visa,
+                billingAddressId, "" /* serverId */));
+    }
+
+    @MediumTest
+    @Feature({"Payments"})
+    public void testCannotMakeActivePaymentWithBasicDebitCard() throws InterruptedException,
+            ExecutionException, TimeoutException {
+        openPageAndClickNodeAndWait("checkBasicDebit", mCanMakePaymentQueryResponded);
+        expectResultContains(new String[]{"false"});
+
+        clickNodeAndWait("buyBasicDebit", mShowFailed);
+        expectResultContains(new String[] {"The payment method is not supported"});
+    }
+
+    @MediumTest
+    @Feature({"Payments"})
+    public void testCannotMakeActivePaymentWithBasicMasterCard() throws InterruptedException,
+            ExecutionException, TimeoutException {
+        openPageAndClickNodeAndWait("checkBasicMasterCard", mCanMakePaymentQueryResponded);
+        expectResultContains(new String[]{"false"});
+
+        reTriggerUIAndWait("buyBasicMasterCard", mReadyForInput);
+    }
+
+    /**
+     * To prevent fingerprinting the user, repeated queries for "basic-card" payment method return
+     * cached results, even if the queries were performed with different sets of "supportedNetworks"
+     * and "supportedTypes" every time.
+     */
+    @MediumTest
+    @Feature({"Payments"})
+    public void testReturnsCachedResultForBasiCard() throws InterruptedException,
+            ExecutionException, TimeoutException {
+        openPageAndClickNodeAndWait("checkBasicVisa", mCanMakePaymentQueryResponded);
+        expectResultContains(new String[]{"true"});
+
+        clickNodeAndWait("checkBasicVisa", mCanMakePaymentQueryResponded);
+        expectResultContains(new String[]{"true"});
+
+        // Cached result for "basic-card" is "true", even though the user does not have a MasterCard
+        // on file.
+        clickNodeAndWait("checkBasicMasterCard", mCanMakePaymentQueryResponded);
+        expectResultContains(new String[]{"true"});
+
+        // Cached result for "basic-card" is "true", even though Chrome cannot distinguish debit
+        // cards from credit cards.
+        clickNodeAndWait("checkBasicDebit", mCanMakePaymentQueryResponded);
+        expectResultContains(new String[]{"true"});
+
+        // Checking for "visa" immediately after "basic-card" triggers throttling.
+        clickNodeAndWait("checkVisa", mCanMakePaymentQueryResponded);
+        expectResultContains(new String[]{"Query quota exceeded"});
+
+        // Checking for "mastercard" immediately after "basic-card" triggers throttling.
+        clickNodeAndWait("checkMasterCard", mCanMakePaymentQueryResponded);
+        expectResultContains(new String[]{"Query quota exceeded"});
+    }
+
+    /**
+     * If the merchant requests supported methods of "mastercard" and "basic-card" with "visa"
+     * network support, then the user should be able to pay via their "visa" card. The merchant will
+     * receive the "basic-card" method name.
+     */
+    @MediumTest
+    @Feature({"Payments"})
+    public void testPayWithBasicCard()  throws InterruptedException, ExecutionException,
+            TimeoutException {
+        openPageAndClickNodeAndWait("checkBasicVisa", mCanMakePaymentQueryResponded);
+        expectResultContains(new String[]{"true"});
+
+        reTriggerUIAndWait("buy", mReadyToPay);
+        clickAndWait(R.id.button_primary, mReadyForUnmaskInput);
+        setTextInCardUnmaskDialogAndWait(R.id.card_unmask_input, "123", mReadyToUnmask);
+        clickCardUnmaskButtonAndWait(DialogInterface.BUTTON_POSITIVE, mDismissed);
+        expectResultContains(new String[] {"Jon Doe", "4111111111111111", "12", "2050",
+                "basic-card", "123"});
+    }
+
+    /**
+     * If the merchant requests supported methods of "mastercard" and "basic-card" with "visa"
+     * network support, then the user should be able to add a "mastercard" card and pay with it. The
+     * merchant will receive the "mastercard" method name.
+     */
+    @MediumTest
+    @Feature({"Payments"})
+    public void testAddMasterCard()  throws InterruptedException, ExecutionException,
+            TimeoutException {
+        triggerUIAndWait(mReadyToPay);
+        clickInPaymentMethodAndWait(R.id.payments_section, mReadyForInput);
+        clickInPaymentMethodAndWait(R.id.payments_add_option_button, mReadyToEdit);
+        setTextInCardEditorAndWait(new String[] {"5555-5555-5555-4444", "Jane Jones"},
+                mEditorTextUpdate);
+        setSpinnerSelectionsInCardEditorAndWait(
+                new int[] {DECEMBER, NEXT_YEAR, FIRST_BILLING_ADDRESS},
+                mBillingAddressChangeProcessed);
+        clickInCardEditorAndWait(R.id.payments_edit_done_button, mReadyToPay);
+        clickAndWait(R.id.button_primary, mReadyForUnmaskInput);
+        setTextInCardUnmaskDialogAndWait(R.id.card_unmask_input, "123", mReadyToUnmask);
+        clickCardUnmaskButtonAndWait(DialogInterface.BUTTON_POSITIVE, mDismissed);
+        expectResultContains(
+                new String[] {"5555555555554444", "12", "Jane Jones", "123", "mastercard"});
+    }
+
+    /**
+     * If the merchant requests supported methods of "mastercard" and "basic-card" with "visa"
+     * network support, then the user should be able to add a new "visa" card and pay with it. The
+     * merchant will receive the "basic-card" method name.
+     */
+    @MediumTest
+    @Feature({"Payments"})
+    public void testAddBasicCard()  throws InterruptedException, ExecutionException,
+            TimeoutException {
+        triggerUIAndWait(mReadyToPay);
+        clickInPaymentMethodAndWait(R.id.payments_section, mReadyForInput);
+        clickInPaymentMethodAndWait(R.id.payments_add_option_button, mReadyToEdit);
+        setTextInCardEditorAndWait(new String[] {"4242-4242-4242-4242", "Jane Jones"},
+                mEditorTextUpdate);
+        setSpinnerSelectionsInCardEditorAndWait(
+                new int[] {DECEMBER, NEXT_YEAR, FIRST_BILLING_ADDRESS},
+                mBillingAddressChangeProcessed);
+        clickInCardEditorAndWait(R.id.payments_edit_done_button, mReadyToPay);
+        clickAndWait(R.id.button_primary, mReadyForUnmaskInput);
+        setTextInCardUnmaskDialogAndWait(R.id.card_unmask_input, "123", mReadyToUnmask);
+        clickCardUnmaskButtonAndWait(DialogInterface.BUTTON_POSITIVE, mDismissed);
+        expectResultContains(
+                new String[] {"4242424242424242", "12", "Jane Jones", "123", "basic-card"});
+    }
+}
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 23dffc02..269ec23 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -3267,6 +3267,10 @@
       "android/webapk/chrome_webapk_host.h",
       "android/webapk/webapk_icon_hasher.cc",
       "android/webapk/webapk_icon_hasher.h",
+      "android/webapk/webapk_install_service.cc",
+      "android/webapk/webapk_install_service.h",
+      "android/webapk/webapk_install_service_factory.cc",
+      "android/webapk/webapk_install_service_factory.h",
       "android/webapk/webapk_installer.cc",
       "android/webapk/webapk_installer.h",
       "android/webapk/webapk_metrics.cc",
diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS
index e79d4888..14e6183 100644
--- a/chrome/browser/DEPS
+++ b/chrome/browser/DEPS
@@ -112,6 +112,7 @@
   "+third_party/WebKit/public/platform/modules/screen_orientation/WebScreenOrientationLockType.h",
   "+third_party/WebKit/public/platform/modules/permissions/permission_status.mojom.h",
   "+third_party/WebKit/public/platform/modules/shapedetection/barcodedetection.mojom.h",
+  "+third_party/WebKit/public/platform/modules/shapedetection/textdetection.mojom.h",
   "+third_party/WebKit/public/platform/modules/webshare/webshare.mojom.h",
   "+third_party/WebKit/public/platform/site_engagement.mojom.h",
   "+third_party/WebKit/public/public_features.h",
diff --git a/chrome/browser/android/banners/app_banner_manager_android.cc b/chrome/browser/android/banners/app_banner_manager_android.cc
index 6dc80eb..a8a21c59 100644
--- a/chrome/browser/android/banners/app_banner_manager_android.cc
+++ b/chrome/browser/android/banners/app_banner_manager_android.cc
@@ -142,14 +142,16 @@
 
 bool AppBannerManagerAndroid::IsWebAppInstalled(
     content::BrowserContext* browser_context,
-    const GURL& start_url) {
-  // Returns true if a WebAPK is installed. Does not check whether a non-WebAPK
-  // web app is installed: this is detected by the content settings check in
-  // AppBannerSettingsHelper::ShouldShowBanner (due to the lack of an API to
-  // detect what is and isn't on the Android homescreen).
-  // This method will still detect the presence of a WebAPK even if Chrome's
-  // data is cleared.
-  return ShortcutHelper::IsWebApkInstalled(start_url);
+    const GURL& start_url,
+    const GURL& manifest_url) {
+  // Returns true if a WebAPK is installed or is being installed.
+  // Does not check whether a non-WebAPK web app is installed: this is detected
+  // by the content settings check in AppBannerSettingsHelper::ShouldShowBanner
+  // (due to the lack of an API to detect what is and isn't on the Android
+  // homescreen). This method will still detect the presence of a WebAPK even if
+  // Chrome's data is cleared.
+  return ShortcutHelper::IsWebApkInstalled(browser_context, start_url,
+                                           manifest_url);
 }
 
 void AppBannerManagerAndroid::PerformInstallableCheck() {
diff --git a/chrome/browser/android/banners/app_banner_manager_android.h b/chrome/browser/android/banners/app_banner_manager_android.h
index 3ad2d27..8fe6f6d 100644
--- a/chrome/browser/android/banners/app_banner_manager_android.h
+++ b/chrome/browser/android/banners/app_banner_manager_android.h
@@ -71,7 +71,8 @@
   int GetIdealIconSizeInPx() override;
   int GetMinimumIconSizeInPx() override;
   bool IsWebAppInstalled(content::BrowserContext* browser_context,
-                         const GURL& start_url) override;
+                         const GURL& start_url,
+                         const GURL& manifest_url) override;
 
   void PerformInstallableCheck() override;
   void OnAppIconFetched(const SkBitmap& bitmap) override;
diff --git a/chrome/browser/android/shortcut_helper.cc b/chrome/browser/android/shortcut_helper.cc
index ac08fd22..1536a9ad 100644
--- a/chrome/browser/android/shortcut_helper.cc
+++ b/chrome/browser/android/shortcut_helper.cc
@@ -15,7 +15,7 @@
 #include "base/strings/string16.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/android/webapk/chrome_webapk_host.h"
-#include "chrome/browser/android/webapk/webapk_installer.h"
+#include "chrome/browser/android/webapk/webapk_install_service.h"
 #include "chrome/browser/manifest/manifest_icon_downloader.h"
 #include "chrome/common/chrome_switches.h"
 #include "content/public/browser/browser_thread.h"
@@ -85,9 +85,8 @@
     const ShortcutInfo& info,
     const SkBitmap& icon_bitmap,
     const WebApkInstaller::FinishCallback& callback) {
-  // WebApkInstaller destroys itself when it is done.
-  WebApkInstaller* installer = new WebApkInstaller(info, icon_bitmap);
-  installer->InstallAsync(browser_context, callback);
+  WebApkInstallService::Get(browser_context)
+      ->InstallAsync(info, icon_bitmap, callback);
 }
 
 // static
@@ -146,6 +145,11 @@
                                   info.source);
 }
 
+void ShortcutHelper::ShowWebApkInstallInProgressToast() {
+  Java_ShortcutHelper_showWebApkInstallInProgressToast(
+      base::android::AttachCurrentThread());
+}
+
 int ShortcutHelper::GetIdealHomescreenIconSizeInPx() {
   if (kIdealHomescreenIconSize == -1)
     GetHomescreenIconAndSplashImageSizes();
@@ -260,8 +264,13 @@
 }
 
 // static
-bool ShortcutHelper::IsWebApkInstalled(const GURL& url) {
-  return !QueryWebApkPackage(url).empty();
+bool ShortcutHelper::IsWebApkInstalled(
+    content::BrowserContext* browser_context,
+    const GURL& start_url,
+    const GURL& manifest_url) {
+  return !QueryWebApkPackage(start_url).empty() ||
+      WebApkInstallService::Get(browser_context)
+      ->IsInstallInProgress(manifest_url);
 }
 
 GURL ShortcutHelper::GetScopeFromURL(const GURL& url) {
diff --git a/chrome/browser/android/shortcut_helper.h b/chrome/browser/android/shortcut_helper.h
index 847c5c1..1c69e53e 100644
--- a/chrome/browser/android/shortcut_helper.h
+++ b/chrome/browser/android/shortcut_helper.h
@@ -59,6 +59,10 @@
       const ShortcutInfo& info,
       const SkBitmap& icon_bitmap);
 
+  // Shows toast notifying user that a WebAPK install is already in progress
+  // when user tries to queue a new install for the same WebAPK.
+  static void ShowWebApkInstallInProgressToast();
+
   // Returns the ideal size for an icon representing a web app.
   static int GetIdealHomescreenIconSizeInPx();
 
@@ -101,8 +105,10 @@
   static std::string QueryWebApkPackage(const GURL& url);
 
   // Returns true if WebAPKs are enabled and there is an installed WebAPK which
-  // can handle |url|.
-  static bool IsWebApkInstalled(const GURL& url);
+  // can handle |start_url|, or there is one is being installed.
+  static bool IsWebApkInstalled(content::BrowserContext* browser_context,
+                                const GURL& start_url,
+                                const GURL& manifest_url);
 
   // Generates a scope URL based on the passed in |url|. It should be used
   // when the Web Manifest does not specify a scope URL.
diff --git a/chrome/browser/android/webapk/webapk_install_service.cc b/chrome/browser/android/webapk/webapk_install_service.cc
new file mode 100644
index 0000000..153543f
--- /dev/null
+++ b/chrome/browser/android/webapk/webapk_install_service.cc
@@ -0,0 +1,70 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/android/webapk/webapk_install_service.h"
+
+#include "base/bind.h"
+#include "chrome/browser/android/shortcut_info.h"
+#include "chrome/browser/android/webapk/webapk_install_service_factory.h"
+#include "chrome/browser/android/webapk/webapk_installer.h"
+
+// static
+WebApkInstallService* WebApkInstallService::Get(
+    content::BrowserContext* context) {
+  return WebApkInstallServiceFactory::GetForBrowserContext(context);
+}
+
+WebApkInstallService::WebApkInstallService(
+    content::BrowserContext* browser_context)
+    : browser_context_(browser_context),
+      weak_ptr_factory_(this) {}
+
+WebApkInstallService::~WebApkInstallService() {}
+
+bool WebApkInstallService::IsInstallInProgress(const GURL& web_manifest_url) {
+  return installs_.count(web_manifest_url);
+}
+
+void WebApkInstallService::InstallAsync(const ShortcutInfo& shortcut_info,
+                                        const SkBitmap& shortcut_icon,
+                                        const FinishCallback& finish_callback) {
+  DCHECK(!IsInstallInProgress(shortcut_info.manifest_url));
+
+  installs_.insert(shortcut_info.manifest_url);
+
+  WebApkInstaller::InstallAsync(
+      browser_context_, shortcut_info, shortcut_icon,
+      base::Bind(&WebApkInstallService::OnFinishedInstall,
+                 weak_ptr_factory_.GetWeakPtr(), shortcut_info.manifest_url,
+                 finish_callback));
+}
+
+void WebApkInstallService::UpdateAsync(
+    const ShortcutInfo& shortcut_info,
+    const SkBitmap& shortcut_icon,
+    const std::string& webapk_package,
+    int webapk_version,
+    const std::map<std::string, std::string>& icon_url_to_murmur2_hash,
+    bool is_manifest_stale,
+    const FinishCallback& finish_callback) {
+  DCHECK(!IsInstallInProgress(shortcut_info.manifest_url));
+
+  installs_.insert(shortcut_info.manifest_url);
+
+  WebApkInstaller::UpdateAsync(
+      browser_context_, shortcut_info, shortcut_icon, webapk_package,
+      webapk_version, icon_url_to_murmur2_hash, is_manifest_stale,
+      base::Bind(&WebApkInstallService::OnFinishedInstall,
+                 weak_ptr_factory_.GetWeakPtr(), shortcut_info.manifest_url,
+                 finish_callback));
+}
+
+void WebApkInstallService::OnFinishedInstall(
+    const GURL& web_manifest_url,
+    const FinishCallback& finish_callback,
+    bool success,
+    const std::string& webapk_package_name) {
+  finish_callback.Run(success, webapk_package_name);
+  installs_.erase(web_manifest_url);
+}
diff --git a/chrome/browser/android/webapk/webapk_install_service.h b/chrome/browser/android/webapk/webapk_install_service.h
new file mode 100644
index 0000000..e22dc9a
--- /dev/null
+++ b/chrome/browser/android/webapk/webapk_install_service.h
@@ -0,0 +1,80 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ANDROID_WEBAPK_WEBAPK_INSTALL_SERVICE_H_
+#define CHROME_BROWSER_ANDROID_WEBAPK_WEBAPK_INSTALL_SERVICE_H_
+
+#include <map>
+#include <set>
+#include <string>
+
+#include "base/callback.h"
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "components/keyed_service/core/keyed_service.h"
+#include "url/gurl.h"
+
+namespace content {
+class BrowserContext;
+}
+
+struct ShortcutInfo;
+class SkBitmap;
+
+// Service which talks to Chrome WebAPK server and Google Play to generate a
+// WebAPK on the server, download it, and install it.
+class WebApkInstallService : public KeyedService {
+ public:
+  // Called when the creation/updating of a WebAPK is finished or failed.
+  // Parameters:
+  // - whether the process succeeds.
+  // - the package name of the WebAPK.
+  using FinishCallback = base::Callback<void(bool, const std::string&)>;
+
+  static WebApkInstallService* Get(content::BrowserContext* browser_context);
+
+  explicit WebApkInstallService(content::BrowserContext* browser_context);
+  ~WebApkInstallService() override;
+
+  // Returns whether an install for |web_manifest_url| is in progress.
+  bool IsInstallInProgress(const GURL& web_manifest_url);
+
+  // Talks to the Chrome WebAPK server to generate a WebAPK on the server and to
+  // Google Play to install the downloaded WebAPK. Calls |callback| once the
+  // install completed or failed.
+  void InstallAsync(const ShortcutInfo& shortcut_info,
+                    const SkBitmap& shortcut_icon,
+                    const FinishCallback& finish_callback);
+
+  // Talks to the Chrome WebAPK server to update a WebAPK on the server and to
+  // the Google Play server to install the downloaded WebAPK. Calls |callback|
+  // after the request to install the WebAPK is sent to Google Play.
+  void UpdateAsync(
+      const ShortcutInfo& shortcut_info,
+      const SkBitmap& shortcut_icon,
+      const std::string& webapk_package,
+      int webapk_version,
+      const std::map<std::string, std::string>& icon_url_to_murmur2_hash,
+      bool is_manifest_stale,
+      const FinishCallback& finish_callback);
+
+ private:
+  // Called once the install/update completed or failed.
+  void OnFinishedInstall(const GURL& web_manifest_url,
+                         const FinishCallback& finish_callback,
+                         bool success,
+                         const std::string& webapk_package_name);
+
+  content::BrowserContext* browser_context_;
+
+  // In progress installs.
+  std::set<GURL> installs_;
+
+  // Used to get |weak_ptr_|.
+  base::WeakPtrFactory<WebApkInstallService> weak_ptr_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(WebApkInstallService);
+};
+
+#endif  // CHROME_BROWSER_ANDROID_WEBAPK_WEBAPK_INSTALL_SERVICE_H_
diff --git a/chrome/browser/android/webapk/webapk_install_service_factory.cc b/chrome/browser/android/webapk/webapk_install_service_factory.cc
new file mode 100644
index 0000000..504532c4
--- /dev/null
+++ b/chrome/browser/android/webapk/webapk_install_service_factory.cc
@@ -0,0 +1,32 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/android/webapk/webapk_install_service_factory.h"
+
+#include "chrome/browser/android/webapk/webapk_install_service.h"
+#include "components/keyed_service/content/browser_context_dependency_manager.h"
+
+// static
+WebApkInstallServiceFactory* WebApkInstallServiceFactory::GetInstance() {
+  return base::Singleton<WebApkInstallServiceFactory>::get();
+}
+
+// static
+WebApkInstallService* WebApkInstallServiceFactory::GetForBrowserContext(
+    content::BrowserContext* context) {
+  return static_cast<WebApkInstallService*>(
+      GetInstance()->GetServiceForBrowserContext(context, true));
+}
+
+WebApkInstallServiceFactory::WebApkInstallServiceFactory()
+    : BrowserContextKeyedServiceFactory(
+          "WebApkInstallService",
+          BrowserContextDependencyManager::GetInstance()) {}
+
+WebApkInstallServiceFactory::~WebApkInstallServiceFactory() {}
+
+KeyedService* WebApkInstallServiceFactory::BuildServiceInstanceFor(
+    content::BrowserContext* context) const {
+  return new WebApkInstallService(context);
+}
diff --git a/chrome/browser/android/webapk/webapk_install_service_factory.h b/chrome/browser/android/webapk/webapk_install_service_factory.h
new file mode 100644
index 0000000..599a081
--- /dev/null
+++ b/chrome/browser/android/webapk/webapk_install_service_factory.h
@@ -0,0 +1,34 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ANDROID_WEBAPK_WEBAPK_INSTALL_SERVICE_FACTORY_H_
+#define CHROME_BROWSER_ANDROID_WEBAPK_WEBAPK_INSTALL_SERVICE_FACTORY_H_
+
+#include "base/macros.h"
+#include "base/memory/singleton.h"
+#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
+
+class WebApkInstallService;
+
+// Factory for creating WebApkInstallService. Installing WebAPKs from incognito
+// is unsupported.
+class WebApkInstallServiceFactory : public BrowserContextKeyedServiceFactory {
+ public:
+  static WebApkInstallServiceFactory* GetInstance();
+  static WebApkInstallService* GetForBrowserContext(
+      content::BrowserContext* context);
+
+ private:
+  friend struct base::DefaultSingletonTraits<WebApkInstallServiceFactory>;
+
+  WebApkInstallServiceFactory();
+  ~WebApkInstallServiceFactory() override;
+
+  KeyedService* BuildServiceInstanceFor(
+      content::BrowserContext* context) const override;
+
+  DISALLOW_COPY_AND_ASSIGN(WebApkInstallServiceFactory);
+};
+
+#endif  // CHROME_BROWSER_ANDROID_WEBAPK_WEBAPK_INSTALL_SERVICE_FACTORY_H_
diff --git a/chrome/browser/android/webapk/webapk_installer.cc b/chrome/browser/android/webapk/webapk_installer.cc
index a34ddd3..1384c59 100644
--- a/chrome/browser/android/webapk/webapk_installer.cc
+++ b/chrome/browser/android/webapk/webapk_installer.cc
@@ -209,87 +209,59 @@
 
 }  // anonymous namespace
 
-WebApkInstaller::WebApkInstaller(const ShortcutInfo& shortcut_info,
-                                 const SkBitmap& shortcut_icon)
-    : shortcut_info_(shortcut_info),
-      shortcut_icon_(shortcut_icon),
-      server_url_(GetServerUrl()),
-      webapk_download_url_timeout_ms_(kWebApkDownloadUrlTimeoutMs),
-      download_timeout_ms_(kDownloadTimeoutMs),
-      task_type_(UNDEFINED),
-      weak_ptr_factory_(this) {
-  CreateJavaRef();
-}
-
-void WebApkInstaller::CreateJavaRef() {
-  JNIEnv* env = base::android::AttachCurrentThread();
-  java_ref_.Reset(Java_WebApkInstaller_create(
-      env, reinterpret_cast<intptr_t>(this)));
-}
-
 WebApkInstaller::~WebApkInstaller() {
   JNIEnv* env = base::android::AttachCurrentThread();
   Java_WebApkInstaller_destroy(env, java_ref_);
   java_ref_.Reset();
 }
 
-void WebApkInstaller::InstallAsync(content::BrowserContext* browser_context,
+// static
+void WebApkInstaller::InstallAsync(content::BrowserContext* context,
+                                   const ShortcutInfo& shortcut_info,
+                                   const SkBitmap& shortcut_icon,
                                    const FinishCallback& finish_callback) {
-  InstallAsyncWithURLRequestContextGetter(
-      Profile::FromBrowserContext(browser_context)->GetRequestContext(),
-      finish_callback);
+  // The installer will delete itself when it is done.
+  WebApkInstaller* installer =
+      new WebApkInstaller(context, shortcut_info, shortcut_icon);
+  installer->InstallAsync(finish_callback);
 }
 
-void WebApkInstaller::InstallAsyncWithURLRequestContextGetter(
-    net::URLRequestContextGetter* request_context_getter,
-    const FinishCallback& finish_callback) {
-  request_context_getter_ = request_context_getter;
-  finish_callback_ = finish_callback;
-  task_type_ = INSTALL;
-
-  // We need to take the hash of the bitmap at the icon URL prior to any
-  // transformations being applied to the bitmap (such as encoding/decoding
-  // the bitmap). The icon hash is used to determine whether the icon that
-  // the user sees matches the icon of a WebAPK that the WebAPK server
-  // generated for another user. (The icon can be dynamically generated.)
-  //
-  // We redownload the icon in order to take the Murmur2 hash. The redownload
-  // should be fast because the icon should be in the HTTP cache.
-  DownloadAppIconAndComputeMurmur2Hash();
-}
-
+// static
 void WebApkInstaller::UpdateAsync(
-    content::BrowserContext* browser_context,
-    const FinishCallback& finish_callback,
+    content::BrowserContext* context,
+    const ShortcutInfo& shortcut_info,
+    const SkBitmap& shortcut_icon,
     const std::string& webapk_package,
     int webapk_version,
     const std::map<std::string, std::string>& icon_url_to_murmur2_hash,
-    bool is_manifest_stale) {
-  UpdateAsyncWithURLRequestContextGetter(
-      Profile::FromBrowserContext(browser_context)->GetRequestContext(),
-      finish_callback, webapk_package, webapk_version,
-      icon_url_to_murmur2_hash, is_manifest_stale);
+    bool is_manifest_stale,
+    const FinishCallback& finish_callback) {
+  // The installer will delete itself when it is done.
+  WebApkInstaller* installer =
+      new WebApkInstaller(context, shortcut_info, shortcut_icon);
+  installer->UpdateAsync(
+      webapk_package, webapk_version, icon_url_to_murmur2_hash,
+      is_manifest_stale, finish_callback);
 }
 
-void WebApkInstaller::UpdateAsyncWithURLRequestContextGetter(
-    net::URLRequestContextGetter* request_context_getter,
-    const FinishCallback& finish_callback,
+// staic
+void WebApkInstaller::InstallAsyncForTesting(
+    WebApkInstaller* installer,
+    const FinishCallback& finish_callback) {
+  installer->InstallAsync(finish_callback);
+}
+
+// static
+void WebApkInstaller::UpdateAsyncForTesting(
+    WebApkInstaller* installer,
     const std::string& webapk_package,
     int webapk_version,
     const std::map<std::string, std::string>& icon_url_to_murmur2_hash,
-    bool is_manifest_stale) {
-  request_context_getter_ = request_context_getter;
-  finish_callback_ = finish_callback;
-  webapk_package_ = webapk_package;
-  webapk_version_ = webapk_version;
-  task_type_ = UPDATE;
-
-  base::PostTaskAndReplyWithResult(
-      GetBackgroundTaskRunner().get(), FROM_HERE,
-      base::Bind(&BuildWebApkProtoInBackground, shortcut_info_, shortcut_icon_,
-                 icon_url_to_murmur2_hash, is_manifest_stale),
-      base::Bind(&WebApkInstaller::SendUpdateWebApkRequest,
-                  weak_ptr_factory_.GetWeakPtr()));
+    bool is_manifest_stale,
+    const FinishCallback& finish_callback) {
+  installer->UpdateAsync(
+      webapk_package, webapk_version, icon_url_to_murmur2_hash,
+      is_manifest_stale, finish_callback);
 }
 
 void WebApkInstaller::SetTimeoutMs(int timeout_ms) {
@@ -371,6 +343,61 @@
   }
 }
 
+WebApkInstaller::WebApkInstaller(content::BrowserContext* browser_context,
+                                 const ShortcutInfo& shortcut_info,
+                                 const SkBitmap& shortcut_icon)
+    : request_context_getter_(
+          Profile::FromBrowserContext(browser_context)->GetRequestContext()),
+      shortcut_info_(shortcut_info),
+      shortcut_icon_(shortcut_icon),
+      server_url_(GetServerUrl()),
+      webapk_download_url_timeout_ms_(kWebApkDownloadUrlTimeoutMs),
+      download_timeout_ms_(kDownloadTimeoutMs),
+      task_type_(UNDEFINED),
+      weak_ptr_factory_(this) {
+  CreateJavaRef();
+}
+
+void WebApkInstaller::CreateJavaRef() {
+  JNIEnv* env = base::android::AttachCurrentThread();
+  java_ref_.Reset(Java_WebApkInstaller_create(
+      env, reinterpret_cast<intptr_t>(this)));
+}
+
+void WebApkInstaller::InstallAsync(const FinishCallback& finish_callback) {
+  finish_callback_ = finish_callback;
+  task_type_ = INSTALL;
+
+  // We need to take the hash of the bitmap at the icon URL prior to any
+  // transformations being applied to the bitmap (such as encoding/decoding
+  // the bitmap). The icon hash is used to determine whether the icon that
+  // the user sees matches the icon of a WebAPK that the WebAPK server
+  // generated for another user. (The icon can be dynamically generated.)
+  //
+  // We redownload the icon in order to take the Murmur2 hash. The redownload
+  // should be fast because the icon should be in the HTTP cache.
+  DownloadAppIconAndComputeMurmur2Hash();
+}
+
+void WebApkInstaller::UpdateAsync(
+    const std::string& webapk_package,
+    int webapk_version,
+    const std::map<std::string, std::string>& icon_url_to_murmur2_hash,
+    bool is_manifest_stale,
+    const FinishCallback& finish_callback) {
+  webapk_package_ = webapk_package;
+  webapk_version_ = webapk_version;
+  finish_callback_ = finish_callback;
+  task_type_ = UPDATE;
+
+  base::PostTaskAndReplyWithResult(
+      GetBackgroundTaskRunner().get(), FROM_HERE,
+      base::Bind(&BuildWebApkProtoInBackground, shortcut_info_, shortcut_icon_,
+                 icon_url_to_murmur2_hash, is_manifest_stale),
+      base::Bind(&WebApkInstaller::SendUpdateWebApkRequest,
+                  weak_ptr_factory_.GetWeakPtr()));
+}
+
 void WebApkInstaller::OnURLFetchComplete(const net::URLFetcher* source) {
   timer_.Stop();
 
diff --git a/chrome/browser/android/webapk/webapk_installer.h b/chrome/browser/android/webapk/webapk_installer.h
index 95ad8fb..a987e04 100644
--- a/chrome/browser/android/webapk/webapk_installer.h
+++ b/chrome/browser/android/webapk/webapk_installer.h
@@ -45,41 +45,45 @@
   // - the package name of the WebAPK.
   using FinishCallback = base::Callback<void(bool, const std::string&)>;
 
-  WebApkInstaller(const ShortcutInfo& shortcut_info,
-                  const SkBitmap& shorcut_icon);
-
   ~WebApkInstaller() override;
 
-  // Talks to the Chrome WebAPK server to generate a WebAPK on the server and to
-  // Google Play to install the downloaded WebAPK. Calls |callback| after the
-  // request to install the WebAPK is sent to Google Play.
-  void InstallAsync(content::BrowserContext* browser_context,
+  // Creates a self-owned WebApkInstaller instance and talks to the Chrome
+  // WebAPK server to generate a WebAPK on the server and to Google Play to
+  // install the downloaded WebAPK. Calls |callback| once the install completed
+  // or failed.
+  static void InstallAsync(content::BrowserContext* context,
+                    const ShortcutInfo& shortcut_info,
+                    const SkBitmap& shortcut_icon,
                     const FinishCallback& finish_callback);
 
-  // Same as InstallAsync() but uses the passed in |request_context_getter|.
-  void InstallAsyncWithURLRequestContextGetter(
-      net::URLRequestContextGetter* request_context_getter,
-      const FinishCallback& finish_callback);
-
-  // Talks to the Chrome WebAPK server to update a WebAPK on the server and to
-  // the Google Play server to install the downloaded WebAPK. Calls |callback|
-  // after the request to install the WebAPK is sent to the Google Play server.
-  void UpdateAsync(
-      content::BrowserContext* browser_context,
-      const FinishCallback& callback,
+  // Creates a self-owned WebApkInstaller instance and talks to the Chrome
+  // WebAPK server to update a WebAPK on the server and to the Google Play
+  // server to install the downloaded WebAPK. Calls |callback| after the request
+  // to install the WebAPK is sent to the Google Play server.
+  static void UpdateAsync(
+      content::BrowserContext* context,
+      const ShortcutInfo& shortcut_info,
+      const SkBitmap& shortcut_icon,
       const std::string& webapk_package,
       int webapk_version,
       const std::map<std::string, std::string>& icon_url_to_murmur2_hash,
-      bool is_manifest_stale);
+      bool is_manifest_stale,
+      const FinishCallback& callback);
 
-  // Same as UpdateAsync() but uses the passed in |request_context_getter|.
-  void UpdateAsyncWithURLRequestContextGetter(
-      net::URLRequestContextGetter* request_context_getter,
-      const FinishCallback& callback,
+  // Calls the private function |InstallAsync| for testing.
+  // Should be used only for testing.
+  static void InstallAsyncForTesting(WebApkInstaller* installer,
+                                     const FinishCallback& finish_callback);
+
+  // Calls the private function |UpdateAsync| for testing.
+  // Should be used only for testing.
+  static void UpdateAsyncForTesting(
+      WebApkInstaller* installer,
       const std::string& webapk_package,
       int webapk_version,
       const std::map<std::string, std::string>& icon_url_to_murmur2_hash,
-      bool is_manifest_stale);
+      bool is_manifest_stale,
+      const FinishCallback& callback);
 
   // Sets the timeout for the server requests.
   void SetTimeoutMs(int timeout_ms);
@@ -100,6 +104,10 @@
   static bool Register(JNIEnv* env);
 
  protected:
+  WebApkInstaller(content::BrowserContext* browser_context,
+                  const ShortcutInfo& shortcut_info,
+                  const SkBitmap& shortcut_icon);
+
   // Starts installation of the downloaded WebAPK. Returns whether the install
   // could be started. The installation may still fail if true is returned.
   // |file_path| is the file path that the WebAPK was downloaded to.
@@ -141,6 +149,21 @@
   // Create the Java object.
   void CreateJavaRef();
 
+  // Talks to the Chrome WebAPK server to generate a WebAPK on the server and to
+  // Google Play to install the downloaded WebAPK. Calls |callback| once the
+  // install completed or failed.
+  void InstallAsync(const FinishCallback& finish_callback);
+
+  // Talks to the Chrome WebAPK server to update a WebAPK on the server and to
+  // the Google Play server to install the downloaded WebAPK. Calls |callback|
+  // after the request to install the WebAPK is sent to the Google Play server.
+  void UpdateAsync(
+      const std::string& webapk_package,
+      int webapk_version,
+      const std::map<std::string, std::string>& icon_url_to_murmur2_hash,
+      bool is_manifest_stale,
+      const FinishCallback& callback);
+
   // net::URLFetcherDelegate:
   void OnURLFetchComplete(const net::URLFetcher* source) override;
 
diff --git a/chrome/browser/android/webapk/webapk_installer_unittest.cc b/chrome/browser/android/webapk/webapk_installer_unittest.cc
index b5ad46d..84265e7 100644
--- a/chrome/browser/android/webapk/webapk_installer_unittest.cc
+++ b/chrome/browser/android/webapk/webapk_installer_unittest.cc
@@ -20,6 +20,7 @@
 #include "chrome/browser/android/shortcut_info.h"
 #include "chrome/browser/android/webapk/webapk.pb.h"
 #include "chrome/common/chrome_switches.h"
+#include "chrome/test/base/testing_profile.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
@@ -57,10 +58,11 @@
 // WebApkInstaller::InstallOrUpdateWebApkFromGooglePlay() are stubbed out.
 class TestWebApkInstaller : public WebApkInstaller {
  public:
-  TestWebApkInstaller(const ShortcutInfo& shortcut_info,
+  TestWebApkInstaller(content::BrowserContext* browser_context,
+                      const ShortcutInfo& shortcut_info,
                       const SkBitmap& shortcut_icon,
                       bool has_google_play_webapk_install_delegate)
-      : WebApkInstaller(shortcut_info, shortcut_icon),
+      : WebApkInstaller(browser_context, shortcut_info, shortcut_icon),
         has_google_play_webapk_install_delegate_(
             has_google_play_webapk_install_delegate) {}
 
@@ -105,9 +107,9 @@
 // Runs the WebApkInstaller installation process/update and blocks till done.
 class WebApkInstallerRunner {
  public:
-  explicit WebApkInstallerRunner(const GURL& best_icon_url)
-      : url_request_context_getter_(new net::TestURLRequestContextGetter(
-            base::ThreadTaskRunnerHandle::Get())),
+  WebApkInstallerRunner(content::BrowserContext* browser_context,
+                        const GURL& best_icon_url)
+      : browser_context_(browser_context),
         best_icon_url_(best_icon_url),
         has_google_play_webapk_install_delegate_(false) {}
 
@@ -118,10 +120,8 @@
   }
 
   void RunInstallWebApk() {
-    WebApkInstaller* installer = CreateWebApkInstaller();
-
-    installer->InstallAsyncWithURLRequestContextGetter(
-        url_request_context_getter_.get(),
+    WebApkInstaller::InstallAsyncForTesting(
+        CreateWebApkInstaller(),
         base::Bind(&WebApkInstallerRunner::OnCompleted,
                    base::Unretained(this)));
     Run();
@@ -133,14 +133,14 @@
     std::map<std::string, std::string> icon_url_to_murmur2_hash {
       {best_icon_url_.spec(), "0"} };
 
-    CreateWebApkInstaller()->UpdateAsyncWithURLRequestContextGetter(
-        url_request_context_getter_.get(),
-        base::Bind(&WebApkInstallerRunner::OnCompleted, base::Unretained(this)),
+    WebApkInstaller::UpdateAsyncForTesting(
+        CreateWebApkInstaller(),
         kDownloadedWebApkPackageName,
         kWebApkVersion,
         icon_url_to_murmur2_hash,
-        false /* is_manifest_stale */);
-
+        false /* is_manifest_stale */,
+        base::Bind(&WebApkInstallerRunner::OnCompleted,
+                   base::Unretained(this)));
     Run();
   }
 
@@ -149,8 +149,9 @@
     info.best_icon_url = best_icon_url_;
 
     // WebApkInstaller owns itself.
-    WebApkInstaller* installer = new TestWebApkInstaller(
-        info, SkBitmap(), has_google_play_webapk_install_delegate_);
+    WebApkInstaller* installer =
+        new TestWebApkInstaller(browser_context_, info, SkBitmap(),
+                                has_google_play_webapk_install_delegate_);
     installer->SetTimeoutMs(100);
     return installer;
   }
@@ -169,8 +170,7 @@
     on_completed_callback_.Run();
   }
 
-  scoped_refptr<net::TestURLRequestContextGetter>
-      url_request_context_getter_;
+  content::BrowserContext* browser_context_;
 
   // The Web Manifest's icon URL.
   const GURL best_icon_url_;
@@ -208,7 +208,8 @@
 // Builds WebApk proto and blocks till done.
 class BuildProtoRunner {
  public:
-  BuildProtoRunner() {}
+  explicit BuildProtoRunner(content::BrowserContext* browser_context)
+      : browser_context_(browser_context) {}
 
   ~BuildProtoRunner() {}
 
@@ -221,7 +222,7 @@
 
     // WebApkInstaller owns itself.
     WebApkInstaller* installer =
-        new TestWebApkInstaller(info, SkBitmap(), false);
+        new TestWebApkInstaller(browser_context_, info, SkBitmap(), false);
     installer->BuildWebApkProtoInBackgroundForTesting(
         base::Bind(&BuildProtoRunner::OnBuiltWebApkProto,
                    base::Unretained(this)),
@@ -242,6 +243,8 @@
     on_completed_callback_.Run();
   }
 
+  content::BrowserContext* browser_context_;
+
   // The populated webapk::WebApk.
   std::unique_ptr<webapk::WebApk> webapk_request_;
 
@@ -269,9 +272,16 @@
                    base::Unretained(this)));
     ASSERT_TRUE(test_server_.Start());
 
+    profile_.reset(new TestingProfile());
+
     SetDefaults();
   }
 
+  void TearDown() override {
+    profile_.reset();
+    base::RunLoop().RunUntilIdle();
+  }
+
   // Sets the best Web Manifest's icon URL.
   void SetBestIconUrl(const GURL& best_icon_url) {
     best_icon_url_ = best_icon_url;
@@ -292,11 +302,12 @@
 
   std::unique_ptr<WebApkInstallerRunner> CreateWebApkInstallerRunner() {
     return std::unique_ptr<WebApkInstallerRunner>(
-        new WebApkInstallerRunner(best_icon_url_));
+        new WebApkInstallerRunner(profile_.get(), best_icon_url_));
   }
 
   std::unique_ptr<BuildProtoRunner> CreateBuildProtoRunner() {
-    return std::unique_ptr<BuildProtoRunner>(new BuildProtoRunner());
+    return std::unique_ptr<BuildProtoRunner>(
+        new BuildProtoRunner(profile_.get()));
   }
 
   net::test_server::EmbeddedTestServer* test_server() { return &test_server_; }
@@ -320,6 +331,7 @@
                : std::unique_ptr<net::test_server::HttpResponse>();
   }
 
+  std::unique_ptr<TestingProfile> profile_;
   content::TestBrowserThreadBundle thread_bundle_;
   net::EmbeddedTestServer test_server_;
 
diff --git a/chrome/browser/android/webapk/webapk_update_manager.cc b/chrome/browser/android/webapk/webapk_update_manager.cc
index e8951658..835cb60 100644
--- a/chrome/browser/android/webapk/webapk_update_manager.cc
+++ b/chrome/browser/android/webapk/webapk_update_manager.cc
@@ -9,7 +9,9 @@
 #include "base/android/jni_array.h"
 #include "base/android/jni_string.h"
 #include "base/bind.h"
-#include "chrome/browser/android/webapk/webapk_installer.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "chrome/browser/android/shortcut_info.h"
+#include "chrome/browser/android/webapk/webapk_install_service.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "content/public/browser/browser_thread.h"
@@ -109,10 +111,15 @@
   std::string webapk_package;
   ConvertJavaStringToUTF8(env, java_webapk_package, &webapk_package);
 
-  WebApkInstaller* installer = new WebApkInstaller(info, best_icon_bitmap);
-  installer->UpdateAsync(
-      profile,
-      base::Bind(&WebApkUpdateManager::OnBuiltWebApk, id),
-      webapk_package, java_webapk_version, icon_url_to_murmur2_hash,
-      java_is_manifest_stale);
+  WebApkInstallService* install_service = WebApkInstallService::Get(profile);
+  if (install_service->IsInstallInProgress(info.manifest_url)) {
+    base::ThreadTaskRunnerHandle::Get()->PostTask(
+        FROM_HERE,
+        base::Bind(&WebApkUpdateManager::OnBuiltWebApk, id, false, ""));
+    return;
+  }
+  install_service->UpdateAsync(
+      info, best_icon_bitmap, webapk_package, java_webapk_version,
+      icon_url_to_murmur2_hash, java_is_manifest_stale,
+      base::Bind(&WebApkUpdateManager::OnBuiltWebApk, id));
 }
diff --git a/chrome/browser/android/webapps/add_to_homescreen_manager.cc b/chrome/browser/android/webapps/add_to_homescreen_manager.cc
index 624a0f0..3103b17 100644
--- a/chrome/browser/android/webapps/add_to_homescreen_manager.cc
+++ b/chrome/browser/android/webapps/add_to_homescreen_manager.cc
@@ -14,6 +14,7 @@
 #include "chrome/browser/android/banners/app_banner_infobar_delegate_android.h"
 #include "chrome/browser/android/shortcut_helper.h"
 #include "chrome/browser/android/webapk/chrome_webapk_host.h"
+#include "chrome/browser/android/webapk/webapk_install_service.h"
 #include "chrome/browser/android/webapk/webapk_metrics.h"
 #include "chrome/browser/banners/app_banner_settings_helper.h"
 #include "content/public/browser/browser_thread.h"
@@ -164,7 +165,13 @@
 void AddToHomescreenManager::OnDataAvailable(const ShortcutInfo& info,
                                              const SkBitmap& icon) {
   if (is_webapk_compatible_) {
-    CreateInfoBarForWebApk(info, icon);
+    WebApkInstallService* install_service =
+        WebApkInstallService::Get(
+            data_fetcher_->web_contents()->GetBrowserContext());
+    if (install_service->IsInstallInProgress(info.manifest_url))
+      ShortcutHelper::ShowWebApkInstallInProgressToast();
+    else
+      CreateInfoBarForWebApk(info, icon);
     return;
   }
 
diff --git a/chrome/browser/banners/app_banner_manager.cc b/chrome/browser/banners/app_banner_manager.cc
index dec9b25..55e03e54 100644
--- a/chrome/browser/banners/app_banner_manager.cc
+++ b/chrome/browser/banners/app_banner_manager.cc
@@ -214,7 +214,8 @@
 
 bool AppBannerManager::IsWebAppInstalled(
     content::BrowserContext* browser_context,
-    const GURL& start_url) {
+    const GURL& start_url,
+    const GURL& manifest_url) {
   return false;
 }
 
@@ -240,7 +241,7 @@
 
 void AppBannerManager::PerformInstallableCheck() {
   if (IsWebAppInstalled(web_contents()->GetBrowserContext(),
-                        manifest_.start_url) &&
+                        manifest_.start_url, manifest_url_) &&
       !IsDebugMode()) {
     ReportStatus(web_contents(), ALREADY_INSTALLED);
     Stop();
diff --git a/chrome/browser/banners/app_banner_manager.h b/chrome/browser/banners/app_banner_manager.h
index 112b6178..4301ca90 100644
--- a/chrome/browser/banners/app_banner_manager.h
+++ b/chrome/browser/banners/app_banner_manager.h
@@ -129,7 +129,8 @@
 
   // Returns true if the webapp at |start_url| has already been installed.
   virtual bool IsWebAppInstalled(content::BrowserContext* browser_context,
-                                 const GURL& start_url);
+                                 const GURL& start_url,
+                                 const GURL& manifest_url);
 
   // Callback invoked by the InstallableManager once it has fetched the page's
   // manifest.
diff --git a/chrome/browser/banners/app_banner_manager_desktop.cc b/chrome/browser/banners/app_banner_manager_desktop.cc
index 82a6da3..415d801 100644
--- a/chrome/browser/banners/app_banner_manager_desktop.cc
+++ b/chrome/browser/banners/app_banner_manager_desktop.cc
@@ -56,7 +56,8 @@
 
 bool AppBannerManagerDesktop::IsWebAppInstalled(
     content::BrowserContext* browser_context,
-    const GURL& start_url) {
+    const GURL& start_url,
+    const GURL& manifest_url) {
   return extensions::BookmarkAppHelper::BookmarkOrHostedAppInstalled(
       browser_context, start_url);
 }
diff --git a/chrome/browser/banners/app_banner_manager_desktop.h b/chrome/browser/banners/app_banner_manager_desktop.h
index 461d686..9ebf13e 100644
--- a/chrome/browser/banners/app_banner_manager_desktop.h
+++ b/chrome/browser/banners/app_banner_manager_desktop.h
@@ -35,7 +35,8 @@
       const extensions::Extension* extension,
       const WebApplicationInfo& web_app_info) override;
   bool IsWebAppInstalled(content::BrowserContext* browser_context,
-                         const GURL& start_url) override;
+                         const GURL& start_url,
+                         const GURL& manifest_url) override;
   void ShowBanner() override;
 
   // content::WebContentsObserver override.
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index 82c986b..ce57133 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -206,6 +206,7 @@
 #include "services/service_manager/public/cpp/service.h"
 #include "storage/browser/fileapi/external_mount_points.h"
 #include "third_party/WebKit/public/platform/modules/shapedetection/barcodedetection.mojom.h"
+#include "third_party/WebKit/public/platform/modules/shapedetection/textdetection.mojom.h"
 #include "third_party/WebKit/public/platform/modules/webshare/webshare.mojom.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/resource/resource_bundle.h"
@@ -3032,6 +3033,9 @@
       registry->AddInterface(
           web_contents->GetJavaInterfaces()
               ->CreateInterfaceFactory<blink::mojom::BarcodeDetection>());
+      registry->AddInterface(
+          web_contents->GetJavaInterfaces()
+              ->CreateInterfaceFactory<blink::mojom::TextDetection>());
     }
   }
 #endif
diff --git a/chrome/browser/chrome_content_browser_manifest_overlay.json b/chrome/browser/chrome_content_browser_manifest_overlay.json
index e217999..427fa05 100644
--- a/chrome/browser/chrome_content_browser_manifest_overlay.json
+++ b/chrome/browser/chrome_content_browser_manifest_overlay.json
@@ -59,6 +59,7 @@
           "autofill::mojom::PasswordManagerDriver",
           "blink::mojom::BarcodeDetection",
           "blink::mojom::ShareService",
+          "blink::mojom::TextDetection",
           "bluetooth::mojom::AdapterFactory",
           "device::usb::ChooserService",
           "device::usb::DeviceManager",
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_file_system_instance_util.cc b/chrome/browser/chromeos/arc/fileapi/arc_file_system_instance_util.cc
index dc1c9e31..9466388ab 100644
--- a/chrome/browser/chromeos/arc/fileapi/arc_file_system_instance_util.cc
+++ b/chrome/browser/chromeos/arc/fileapi/arc_file_system_instance_util.cc
@@ -14,6 +14,14 @@
 #include "content/public/browser/browser_thread.h"
 #include "url/gurl.h"
 
+#define GET_FILE_SYSTEM_INSTANCE(method_name)                      \
+  (arc::ArcServiceManager::Get()                                   \
+       ? ARC_GET_INSTANCE_FOR_METHOD(arc::ArcServiceManager::Get() \
+                                         ->arc_bridge_service()    \
+                                         ->file_system(),          \
+                                     method_name)                  \
+       : nullptr)
+
 using content::BrowserThread;
 
 namespace arc {
@@ -22,28 +30,6 @@
 
 namespace {
 
-constexpr uint32_t kGetFileSizeVersion = 1;
-constexpr uint32_t kOpenFileToReadVersion = 1;
-constexpr uint32_t kGetDocumentVersion = 2;
-constexpr uint32_t kGetChildDocumentsVersion = 2;
-
-// Returns FileSystemInstance for the given |min_version|, if found.
-// Otherwise, nullptr.
-mojom::FileSystemInstance* GetFileSystemInstance(
-    const std::string& method_name_for_logging,
-    uint32_t min_version) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  auto* arc_service_manager = arc::ArcServiceManager::Get();
-  if (!arc_service_manager) {
-    LOG(ERROR) << "Failed to get ArcServiceManager.";
-    return nullptr;
-  }
-  // TODO(lhchavez): Stop calling GetInstanceForVersion() directly.
-  return arc_service_manager->arc_bridge_service()
-      ->file_system()
-      ->GetInstanceForVersion(min_version, method_name_for_logging.c_str());
-}
-
 template <typename T>
 void PostToIOThread(const base::Callback<void(T)>& callback, T result) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -55,8 +41,7 @@
 void GetFileSizeOnUIThread(const GURL& arc_url,
                            const GetFileSizeCallback& callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  auto* file_system_instance =
-      GetFileSystemInstance("GetFileSize", kGetFileSizeVersion);
+  auto* file_system_instance = GET_FILE_SYSTEM_INSTANCE(GetFileSize);
   if (!file_system_instance) {
     callback.Run(-1);
     return;
@@ -67,8 +52,7 @@
 void OpenFileToReadOnUIThread(const GURL& arc_url,
                               const OpenFileToReadCallback& callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  auto* file_system_instance =
-      GetFileSystemInstance("OpenFileToRead", kOpenFileToReadVersion);
+  auto* file_system_instance = GET_FILE_SYSTEM_INSTANCE(OpenFileToRead);
   if (!file_system_instance) {
     callback.Run(mojo::ScopedHandle());
     return;
@@ -80,8 +64,7 @@
                            const std::string& document_id,
                            const GetDocumentCallback& callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  auto* file_system_instance =
-      GetFileSystemInstance("GetDocument", kGetDocumentVersion);
+  auto* file_system_instance = GET_FILE_SYSTEM_INSTANCE(GetDocument);
   if (!file_system_instance) {
     callback.Run(mojom::DocumentPtr());
     return;
@@ -93,8 +76,7 @@
                                  const std::string& parent_document_id,
                                  const GetChildDocumentsCallback& callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  auto* file_system_instance =
-      GetFileSystemInstance("GetChildDocuments", kGetChildDocumentsVersion);
+  auto* file_system_instance = GET_FILE_SYSTEM_INSTANCE(GetChildDocuments);
   if (!file_system_instance) {
     callback.Run(base::nullopt);
     return;
diff --git a/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc b/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc
index 69cfd89..e8bb2aa 100644
--- a/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc
+++ b/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc
@@ -359,6 +359,8 @@
     bool was_cached,
     int net_error,
     int64_t total_received_bytes,
+    int64_t raw_body_bytes,
+    base::TimeTicks request_creation_time,
     base::TimeDelta request_loading_time) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   content::WebContents* web_contents = web_contents_getter.Run();
@@ -374,7 +376,8 @@
       page_load_metrics::MetricsWebContentsObserver::FromWebContents(
           web_contents);
   if (metrics_observer) {
-    metrics_observer->OnRequestComplete(resource_type, was_cached, net_error);
+    metrics_observer->OnRequestComplete(resource_type, was_cached,
+                                        raw_body_bytes, request_creation_time);
   }
 }
 
@@ -836,6 +839,7 @@
                  info->GetWebContentsGetterForRequest(), url_request->url(),
                  info->GetResourceType(), url_request->was_cached(), net_error,
                  url_request->GetTotalReceivedBytes(),
+                 url_request->GetRawBodyBytes(), url_request->creation_time(),
                  base::TimeTicks::Now() - url_request->creation_time()));
 }
 
diff --git a/chrome/browser/page_load_metrics/metrics_web_contents_observer.cc b/chrome/browser/page_load_metrics/metrics_web_contents_observer.cc
index b51abec..da214d8 100644
--- a/chrome/browser/page_load_metrics/metrics_web_contents_observer.cc
+++ b/chrome/browser/page_load_metrics/metrics_web_contents_observer.cc
@@ -178,17 +178,20 @@
 void MetricsWebContentsObserver::OnRequestComplete(
     content::ResourceType resource_type,
     bool was_cached,
-    int net_error) {
-  // For simplicity, only count subresources. Navigations are hard to attribute
-  // here because we won't have a committed load by the time data streams in
-  // from the IO thread.
-  if (resource_type == content::RESOURCE_TYPE_MAIN_FRAME &&
-      net_error != net::OK) {
+    int64_t raw_body_bytes,
+    base::TimeTicks creation_time) {
+  // If the navigation hasn't committed yet then we'll miss the resource (this
+  // happens on the new tab page). Also, if the resource request was started
+  // before this navigation then it should be ignored.
+  // TODO(jkarlin): There is a race here. If a renderer starts URLRequests for
+  // page A after navigating (but before comitting) to page B, then page A's
+  // requests might wind up counting toward page B's size. This should be
+  // relatively rare but we may want to fix this at some point.
+  if (!committed_load_ || creation_time < committed_load_->navigation_start()) {
     return;
   }
-  if (!committed_load_)
-    return;
-  committed_load_->OnLoadedSubresource(was_cached);
+
+  committed_load_->OnLoadedResource(was_cached, raw_body_bytes);
 }
 
 const PageLoadExtraInfo
diff --git a/chrome/browser/page_load_metrics/metrics_web_contents_observer.h b/chrome/browser/page_load_metrics/metrics_web_contents_observer.h
index 02d4a80..866a369 100644
--- a/chrome/browser/page_load_metrics/metrics_web_contents_observer.h
+++ b/chrome/browser/page_load_metrics/metrics_web_contents_observer.h
@@ -72,7 +72,8 @@
   // A resource request completed on the IO thread.
   void OnRequestComplete(content::ResourceType resource_type,
                          bool was_cached,
-                         int net_error);
+                         int64_t raw_body_bytes,
+                         base::TimeTicks creation_time);
 
   // Flush any buffered metrics, as part of the metrics subsystem persisting
   // metrics as the application goes into the background. The application may be
diff --git a/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer.cc
index 6d6e2b5..f137a0d 100644
--- a/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer.cc
+++ b/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer.cc
@@ -203,6 +203,10 @@
 const char kHistogramFirstScrollInputAfterFirstPaint[] =
     "PageLoad.InputTiming.NavigationToFirstScroll.AfterPaint";
 
+const char kHistogramTotalBytes[] = "PageLoad.Experimental.Bytes.Total";
+const char kHistogramNetworkBytes[] = "PageLoad.Experimental.Bytes.Network";
+const char kHistogramCacheBytes[] = "PageLoad.Experimental.Bytes.Cache";
+
 }  // namespace internal
 
 CorePageLoadMetricsObserver::CorePageLoadMetricsObserver()
@@ -532,6 +536,20 @@
     const page_load_metrics::PageLoadExtraInfo& info) {
   RecordTimingHistograms(timing, info);
   RecordRappor(timing, info);
+
+  int64_t total_kb = (info.network_bytes + info.cache_bytes) / 1024;
+  int64_t network_kb = info.network_bytes / 1024;
+  int64_t cache_kb = info.cache_bytes / 1024;
+  DCHECK_LE(network_kb, total_kb);
+  DCHECK_LE(cache_kb, total_kb);
+  DCHECK_LE(total_kb, std::numeric_limits<int>::max());
+
+  UMA_HISTOGRAM_CUSTOM_COUNTS(internal::kHistogramNetworkBytes,
+                              static_cast<int>(network_kb), 1, 500 * 1024, 50);
+  UMA_HISTOGRAM_CUSTOM_COUNTS(internal::kHistogramCacheBytes,
+                              static_cast<int>(cache_kb), 1, 500 * 1024, 50);
+  UMA_HISTOGRAM_CUSTOM_COUNTS(internal::kHistogramTotalBytes,
+                              static_cast<int>(total_kb), 1, 500 * 1024, 50);
 }
 
 void CorePageLoadMetricsObserver::OnFailedProvisionalLoad(
diff --git a/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer.h b/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer.h
index d7ccb32..98f7df39 100644
--- a/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer.h
+++ b/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer.h
@@ -47,6 +47,10 @@
 extern const char kHistogramFirstNonScrollInputAfterFirstPaint[];
 extern const char kHistogramFirstScrollInputAfterFirstPaint[];
 
+extern const char kHistogramTotalBytes[];
+extern const char kHistogramNetworkBytes[];
+extern const char kHistogramCacheBytes[];
+
 enum FirstMeaningfulPaintStatus {
   FIRST_MEANINGFUL_PAINT_RECORDED,
   FIRST_MEANINGFUL_PAINT_BACKGROUNDED,
diff --git a/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer_unittest.cc
index bbd1bbe..47f3cd7 100644
--- a/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer_unittest.cc
+++ b/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer_unittest.cc
@@ -482,6 +482,14 @@
       timing.parse_start.value().InMilliseconds(), 1);
 }
 
+TEST_F(CorePageLoadMetricsObserverTest, BytesCounted) {
+  NavigateAndCommit(GURL(kDefaultTestUrl));
+  NavigateAndCommit(GURL(kDefaultTestUrl2));
+  histogram_tester().ExpectTotalCount(internal::kHistogramTotalBytes, 1);
+  histogram_tester().ExpectTotalCount(internal::kHistogramNetworkBytes, 1);
+  histogram_tester().ExpectTotalCount(internal::kHistogramCacheBytes, 1);
+}
+
 TEST_F(CorePageLoadMetricsObserverTest, FirstMeaningfulPaint) {
   page_load_metrics::PageLoadTiming timing;
   timing.navigation_start = base::Time::FromDoubleT(1);
diff --git a/chrome/browser/page_load_metrics/page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/page_load_metrics_observer.cc
index cb27c0d8..0135bc68 100644
--- a/chrome/browser/page_load_metrics/page_load_metrics_observer.cc
+++ b/chrome/browser/page_load_metrics/page_load_metrics_observer.cc
@@ -18,6 +18,8 @@
     const base::Optional<base::TimeDelta>& time_to_abort,
     int num_cache_requests,
     int num_network_requests,
+    int64_t cache_bytes,
+    int64_t network_bytes,
     const PageLoadMetadata& metadata)
     : first_background_time(first_background_time),
       first_foreground_time(first_foreground_time),
@@ -30,6 +32,8 @@
       time_to_abort(time_to_abort),
       num_cache_requests(num_cache_requests),
       num_network_requests(num_network_requests),
+      cache_bytes(cache_bytes),
+      network_bytes(network_bytes),
       metadata(metadata) {}
 
 PageLoadExtraInfo::PageLoadExtraInfo(const PageLoadExtraInfo& other) = default;
diff --git a/chrome/browser/page_load_metrics/page_load_metrics_observer.h b/chrome/browser/page_load_metrics/page_load_metrics_observer.h
index 7d4c1af..3e7bbf5a 100644
--- a/chrome/browser/page_load_metrics/page_load_metrics_observer.h
+++ b/chrome/browser/page_load_metrics/page_load_metrics_observer.h
@@ -118,6 +118,8 @@
       const base::Optional<base::TimeDelta>& time_to_abort,
       int num_cache_requests,
       int num_network_requests,
+      int64_t cache_bytes,
+      int64_t net_bytes,
       const PageLoadMetadata& metadata);
 
   PageLoadExtraInfo(const PageLoadExtraInfo& other);
@@ -168,6 +170,11 @@
   int num_cache_requests;
   int num_network_requests;
 
+  // The number of body (not header) prefilter bytes consumed by requests for
+  // the page.
+  int64_t cache_bytes;
+  int64_t network_bytes;
+
   // Extra information supplied to the page load metrics system from the
   // renderer.
   const PageLoadMetadata metadata;
@@ -298,7 +305,8 @@
   // OnComplete is invoked for tracked page loads that committed, immediately
   // before the observer is deleted. Observers that implement OnComplete may
   // also want to implement FlushMetricsOnAppEnterBackground, to avoid loss of
-  // data if the application is killed while in the background.
+  // data if the application is killed while in the background (this happens
+  // frequently on Android).
   virtual void OnComplete(const PageLoadTiming& timing,
                           const PageLoadExtraInfo& extra_info) {}
 
diff --git a/chrome/browser/page_load_metrics/page_load_tracker.cc b/chrome/browser/page_load_metrics/page_load_tracker.cc
index 6c1b4a72..55a2dbf 100644
--- a/chrome/browser/page_load_metrics/page_load_tracker.cc
+++ b/chrome/browser/page_load_metrics/page_load_tracker.cc
@@ -300,6 +300,8 @@
       page_transition_(navigation_handle->GetPageTransition()),
       num_cache_requests_(0),
       num_network_requests_(0),
+      cache_bytes_(0),
+      network_bytes_(0),
       user_initiated_info_(user_initiated_info),
       aborted_chain_size_(aborted_chain_size),
       aborted_chain_size_same_url_(aborted_chain_size_same_url),
@@ -520,11 +522,14 @@
   return false;
 }
 
-void PageLoadTracker::OnLoadedSubresource(bool was_cached) {
+void PageLoadTracker::OnLoadedResource(bool was_cached,
+                                       int64_t raw_body_bytes) {
   if (was_cached) {
     ++num_cache_requests_;
+    cache_bytes_ += raw_body_bytes;
   } else {
     ++num_network_requests_;
+    network_bytes_ += raw_body_bytes;
   }
 }
 
@@ -597,7 +602,7 @@
       first_background_time, first_foreground_time, started_in_foreground_,
       user_initiated_info_, committed_url_, start_url_, abort_type_,
       abort_user_initiated_info_, time_to_abort, num_cache_requests_,
-      num_network_requests_, metadata_);
+      num_network_requests_, cache_bytes_, network_bytes_, metadata_);
 }
 
 void PageLoadTracker::NotifyAbort(UserAbortType abort_type,
diff --git a/chrome/browser/page_load_metrics/page_load_tracker.h b/chrome/browser/page_load_metrics/page_load_tracker.h
index 817bc4fd..b58a863 100644
--- a/chrome/browser/page_load_metrics/page_load_tracker.h
+++ b/chrome/browser/page_load_metrics/page_load_tracker.h
@@ -152,7 +152,7 @@
   bool UpdateTiming(const PageLoadTiming& timing,
                     const PageLoadMetadata& metadata);
 
-  void OnLoadedSubresource(bool was_cached);
+  void OnLoadedResource(bool was_cached, int64_t raw_body_bytes);
 
   // Signals that we should stop tracking metrics for the associated page load.
   // We may stop tracking a page load if it doesn't meet the criteria for
@@ -285,6 +285,11 @@
   int num_cache_requests_;
   int num_network_requests_;
 
+  // The number of body (not header) prefilter bytes consumed by requests for
+  // the page.
+  int64_t cache_bytes_;
+  int64_t network_bytes_;
+
   // Whether this page load was user initiated.
   UserInitiatedInfo user_initiated_info_;
 
diff --git a/chrome/browser/predictors/resource_prefetch_predictor.h b/chrome/browser/predictors/resource_prefetch_predictor.h
index a7ce8bf..ae2a57c 100644
--- a/chrome/browser/predictors/resource_prefetch_predictor.h
+++ b/chrome/browser/predictors/resource_prefetch_predictor.h
@@ -50,9 +50,10 @@
 // The overall flow of the resource prefetching algorithm is as follows:
 //
 // * ResourcePrefetchPredictorObserver - Listens for URL requests, responses and
-//   redirects on the IO thread (via ResourceDispatcherHostDelegate) and posts
-//   tasks to the ResourcePrefetchPredictor on the UI thread. This is owned by
-//   the ProfileIOData for the profile.
+//   redirects (client-side redirects are not supported) on the IO thread (via
+//   ResourceDispatcherHostDelegate) and posts tasks to the
+//   ResourcePrefetchPredictor on the UI thread. This is owned by the
+//   ProfileIOData for the profile.
 // * ResourcePrefetchPredictorTables - Persists ResourcePrefetchPredictor data
 //   to a sql database. Runs entirely on the DB thread. Owned by the
 //   PredictorDatabase.
diff --git a/chrome/browser/predictors/resource_prefetch_predictor_browsertest.cc b/chrome/browser/predictors/resource_prefetch_predictor_browsertest.cc
index 2330101..cf305a3 100644
--- a/chrome/browser/predictors/resource_prefetch_predictor_browsertest.cc
+++ b/chrome/browser/predictors/resource_prefetch_predictor_browsertest.cc
@@ -33,6 +33,7 @@
 
 const char kFooHost[] = "foo.com";
 const char kBarHost[] = "bar.com";
+const char kBazHost[] = "baz.com";
 
 const char kImageMime[] = "image/png";
 const char kStyleMime[] = "text/css";
@@ -62,6 +63,8 @@
 const char kHtmlXHRPath[] = "/predictors/xhr.html";
 const char kScriptXHRPath[] = "/predictors/xhr.js";
 const char kHtmlIframePath[] = "/predictors/html_iframe.html";
+const char kHtmlJavascriptRedirectPath[] =
+    "/predictors/javascript_redirect.html";
 
 struct ResourceSummary {
   ResourceSummary()
@@ -90,6 +93,7 @@
   // This response code should be returned by previous url in the chain.
   net::HttpStatusCode code;
   GURL url;
+  bool is_client_side;
 };
 
 // Helper class to track and allow waiting for ResourcePrefetchPredictor
@@ -187,6 +191,24 @@
   return base::StringPrintf("'%zu%s'", version, path.c_str());
 }
 
+GURL GetRequestURL(const net::test_server::HttpRequest& request) {
+  GURL resource_url = request.GetURL();
+  // Retrieve the host that was used in the request because
+  // resource_url contains a resolved host (e.g. 127.0.0.1).
+  if (request.headers.find("Host") != request.headers.end()) {
+    auto host_port_pair =
+        net::HostPortPair::FromString(request.headers.at("Host"));
+    GURL::Replacements replace_host;
+    replace_host.SetHostStr(host_port_pair.host());
+    resource_url = resource_url.ReplaceComponents(replace_host);
+  } else {
+    ADD_FAILURE() << "Host header was not found in a HttpRequest to url: "
+                  << resource_url.spec();
+  }
+
+  return resource_url;
+}
+
 }  // namespace
 
 // Helper class to track and allow waiting for a single OnNavigationLearned
@@ -304,11 +326,15 @@
     PrefetchURL(main_frame_url);
     // To be sure that the browser send no requests to the server after
     // prefetching.
+    NavigateToURLAndCheckSubresourcesAllCached(main_frame_url);
+  }
+
+  void NavigateToURLAndCheckSubresourcesAllCached(const GURL& navigation_url) {
     for (auto& kv : resources_) {
       if (kv.second.is_observable)
         kv.second.is_prohibited = true;
     }
-    NavigateToURLAndCheckSubresources(main_frame_url);
+    NavigateToURLAndCheckSubresources(navigation_url);
     for (auto& kv : resources_) {
       if (kv.second.is_observable)
         kv.second.is_prohibited = false;
@@ -316,14 +342,15 @@
   }
 
   void NavigateToURLAndCheckSubresources(
-      const GURL& main_frame_url,
+      const GURL& navigation_url,
       WindowOpenDisposition disposition = WindowOpenDisposition::CURRENT_TAB) {
-    GURL endpoint_url = GetRedirectEndpoint(main_frame_url);
+    GURL initial_url = GetLastClientSideRedirectEndpoint(navigation_url);
+    GURL main_frame_url = GetRedirectEndpoint(navigation_url);
     std::vector<URLRequestSummary> url_request_summaries;
     for (const auto& kv : resources_) {
       if (kv.second.is_observable) {
         url_request_summaries.push_back(
-            GetURLRequestSummaryForResource(endpoint_url, kv.second));
+            GetURLRequestSummaryForResource(main_frame_url, kv.second));
       }
     }
 
@@ -331,14 +358,15 @@
         disposition == WindowOpenDisposition::CURRENT_TAB;
 
     LearningObserver observer(
-        predictor_, UpdateAndGetVisitCount(main_frame_url),
-        CreatePageRequestSummary(endpoint_url.spec(), main_frame_url.spec(),
+        predictor_, UpdateAndGetVisitCount(initial_url),
+        CreatePageRequestSummary(main_frame_url.spec(), initial_url.spec(),
                                  url_request_summaries),
         match_navigation_id);
     ui_test_utils::NavigateToURLWithDisposition(
-        browser(), main_frame_url, disposition,
+        browser(), navigation_url, disposition,
         ui_test_utils::BROWSER_TEST_NONE);
     observer.Wait();
+
     for (auto& kv : resources_) {
       if (kv.second.is_observable)
         kv.second.request.was_cached = true;
@@ -357,6 +385,10 @@
     }
   }
 
+  void TryToPrefetchURL(const GURL& main_frame_url) {
+    predictor_->StartPrefetching(main_frame_url, PrefetchOrigin::EXTERNAL);
+  }
+
   ResourceSummary* AddResource(const GURL& resource_url,
                                content::ResourceType resource_type,
                                net::RequestPriority priority) {
@@ -490,6 +522,21 @@
     return current;
   }
 
+  GURL GetLastClientSideRedirectEndpoint(const GURL& initial_url) const {
+    GURL last_client_side_redirect_url = initial_url;
+    GURL current = initial_url;
+    while (true) {
+      std::map<GURL, RedirectEdge>::const_iterator it =
+          redirects_.find(current);
+      if (it == redirects_.end())
+        break;
+      current = it->second.url;
+      if (it->second.is_client_side)
+        last_client_side_redirect_url = current;
+    }
+    return last_client_side_redirect_url;
+  }
+
   void MonitorResourceRequest(
       const net::test_server::HttpRequest& request) const {
     std::map<GURL, ResourceSummary>::const_iterator resource_it =
@@ -512,22 +559,8 @@
   //      ETag values match, the handler responds with a HTTP 304 status.
   std::unique_ptr<net::test_server::HttpResponse> HandleResourceRequest(
       const net::test_server::HttpRequest& request) const {
-    GURL resource_url = request.GetURL();
-    // Retrieve the host that was used in the request because
-    // resource_url contains a resolved host (e.g. 127.0.0.1).
-    if (request.headers.find("Host") != request.headers.end()) {
-      auto host_port_pair =
-          net::HostPortPair::FromString(request.headers.at("Host"));
-      GURL::Replacements replace_host;
-      replace_host.SetHostStr(host_port_pair.host());
-      resource_url = resource_url.ReplaceComponents(replace_host);
-    } else {
-      ADD_FAILURE() << "Host header was not found in a HttpRequest to url: "
-                    << resource_url.spec();
-    }
-
     std::map<GURL, ResourceSummary>::const_iterator resource_it =
-        resources_.find(resource_url);
+        resources_.find(GetRequestURL(request));
     if (resource_it == resources_.end())
       return nullptr;
 
@@ -560,6 +593,7 @@
       http_response->AddCustomHeader("Cache-Control", "no-cache");
     else
       http_response->AddCustomHeader("Cache-Control", "max-age=2147483648");
+
     return std::move(http_response);
   }
 
@@ -570,8 +604,8 @@
   std::unique_ptr<net::test_server::HttpResponse> HandleRedirectRequest(
       const net::test_server::HttpRequest& request) const {
     std::map<GURL, RedirectEdge>::const_iterator redirect_it =
-        redirects_.find(request.GetURL());
-    if (redirect_it == redirects_.end())
+        redirects_.find(GetRequestURL(request));
+    if (redirect_it == redirects_.end() || redirect_it->second.is_client_side)
       return nullptr;
 
     auto http_response =
@@ -606,21 +640,25 @@
 }
 
 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, Redirect) {
-  AddRedirectChain(GetURL(kRedirectPath), {{net::HTTP_MOVED_PERMANENTLY,
-                                            GetURL(kHtmlSubresourcesPath)}});
+  GURL initial_url = embedded_test_server()->GetURL(kFooHost, kRedirectPath);
+  AddRedirectChain(initial_url, {{net::HTTP_MOVED_PERMANENTLY,
+                                  GetURL(kHtmlSubresourcesPath)}});
   AddResource(GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, net::LOWEST);
   AddResource(GetURL(kStylePath), content::RESOURCE_TYPE_STYLESHEET,
               net::HIGHEST);
   AddResource(GetURL(kScriptPath), content::RESOURCE_TYPE_SCRIPT, net::MEDIUM);
   AddResource(GetURL(kFontPath), content::RESOURCE_TYPE_FONT_RESOURCE,
               net::HIGHEST);
-  TestLearningAndPrefetching(GetURL(kRedirectPath));
+  TestLearningAndPrefetching(initial_url);
 }
 
 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, RedirectChain) {
-  AddRedirectChain(GetURL(kRedirectPath),
-                   {{net::HTTP_FOUND, GetURL(kRedirectPath2)},
-                    {net::HTTP_MOVED_PERMANENTLY, GetURL(kRedirectPath3)},
+  GURL initial_url = embedded_test_server()->GetURL(kFooHost, kRedirectPath);
+  AddRedirectChain(initial_url,
+                   {{net::HTTP_FOUND,
+                     embedded_test_server()->GetURL(kBarHost, kRedirectPath2)},
+                    {net::HTTP_MOVED_PERMANENTLY,
+                     embedded_test_server()->GetURL(kBazHost, kRedirectPath3)},
                     {net::HTTP_FOUND, GetURL(kHtmlSubresourcesPath)}});
   AddResource(GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, net::LOWEST);
   AddResource(GetURL(kStylePath), content::RESOURCE_TYPE_STYLESHEET,
@@ -628,13 +666,14 @@
   AddResource(GetURL(kScriptPath), content::RESOURCE_TYPE_SCRIPT, net::MEDIUM);
   AddResource(GetURL(kFontPath), content::RESOURCE_TYPE_FONT_RESOURCE,
               net::HIGHEST);
-  TestLearningAndPrefetching(GetURL(kRedirectPath));
+  TestLearningAndPrefetching(initial_url);
 }
 
 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest,
                        HttpToHttpsRedirect) {
   EnableHttpsServer();
-  AddRedirectChain(GetURL(kRedirectPath),
+  GURL initial_url = embedded_test_server()->GetURL(kFooHost, kRedirectPath);
+  AddRedirectChain(initial_url,
                    {{net::HTTP_MOVED_PERMANENTLY,
                      https_server()->GetURL(kHtmlSubresourcesPath)}});
   AddResource(https_server()->GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE,
@@ -645,7 +684,7 @@
               content::RESOURCE_TYPE_SCRIPT, net::MEDIUM);
   AddResource(https_server()->GetURL(kFontPath),
               content::RESOURCE_TYPE_FONT_RESOURCE, net::HIGHEST);
-  TestLearningAndPrefetching(GetURL(kRedirectPath));
+  TestLearningAndPrefetching(initial_url);
 }
 
 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest,
@@ -797,4 +836,41 @@
   TestLearningAndPrefetching(GetURL(kHtmlSubresourcesPath));
 }
 
+// Client-side redirects currently aren't tracked by ResourcePrefetchPredictor.
+// A client-side redirect initiates a new navigation to the redirect destination
+// URL and aborts the current navigation so that the OnLoad event is not fired.
+IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest,
+                       JavascriptRedirectsAreNotHandled) {
+  std::string redirect_path_with_query =
+      std::string(kHtmlJavascriptRedirectPath) + "?url=" +
+      GetURL(kHtmlSubresourcesPath).spec();
+  GURL initial_url =
+      embedded_test_server()->GetURL(kBarHost, redirect_path_with_query);
+  AddRedirectChain(initial_url, {{net::HTTP_TEMPORARY_REDIRECT,
+                                  GetURL(kHtmlSubresourcesPath), true}});
+  AddResource(GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, net::LOWEST);
+  AddResource(GetURL(kStylePath), content::RESOURCE_TYPE_STYLESHEET,
+              net::HIGHEST);
+  AddResource(GetURL(kScriptPath), content::RESOURCE_TYPE_SCRIPT, net::MEDIUM);
+  AddResource(GetURL(kFontPath), content::RESOURCE_TYPE_FONT_RESOURCE,
+              net::HIGHEST);
+
+  // Two navigations will occur. LearningObserver will get events only for the
+  // second navigation because the first one will be aborted.
+  NavigateToURLAndCheckSubresources(initial_url);
+  ClearCache();
+  // It is needed to have at least two resource hits to trigger prefetch.
+  NavigateToURLAndCheckSubresources(initial_url);
+  ClearCache();
+  // Prefetching of |initial_url| has no effect because there is no entry in
+  // the predictor database corresponding the client-side redirect.
+  TryToPrefetchURL(initial_url);
+  NavigateToURLAndCheckSubresources(initial_url);
+  ClearCache();
+  // But the predictor database contains all subresources for the endpoint url
+  // so this prefetch works.
+  PrefetchURL(GetURL(kHtmlSubresourcesPath));
+  NavigateToURLAndCheckSubresourcesAllCached(GetURL(kHtmlSubresourcesPath));
+}
+
 }  // namespace predictors
diff --git a/chrome/browser/prerender/prerender_browsertest.cc b/chrome/browser/prerender/prerender_browsertest.cc
index 88349192..21dbd85 100644
--- a/chrome/browser/prerender/prerender_browsertest.cc
+++ b/chrome/browser/prerender/prerender_browsertest.cc
@@ -546,7 +546,7 @@
       page_load_metrics::UserInitiatedInfo::BrowserInitiated(), dest_url,
       dest_url, page_load_metrics::ABORT_NONE,
       page_load_metrics::UserInitiatedInfo::NotUserInitiated(),
-      base::TimeDelta(), 0, 0, page_load_metrics::PageLoadMetadata());
+      base::TimeDelta(), 0, 0, 0, 0, page_load_metrics::PageLoadMetadata());
 }
 
 }  // namespace
@@ -1083,7 +1083,7 @@
   histogram_tester().ExpectTotalCount(
       "PageLoad.DocumentTiming.NavigationToFirstLayout", 1);
   histogram_tester().ExpectTotalCount(
-      "PageLoad.PaintTiming.NavigationToFirstContentfulPaint", 1);
+      "PageLoad.ParseTiming.NavigationToParseStart", 1);
 
   // Histogram only emitted during a prerender, which should not happen here.
   histogram_tester().ExpectTotalCount(
@@ -1092,13 +1092,7 @@
 
 // Checks that the correct page load metrics observers are produced with a
 // prerender.
-// TODO(https://crbug.com/678976) Fails on ChromeOS and Linux.
-#if defined(OS_CHROMEOS) || defined(OS_LINUX)
-#define MAYBE_PageLoadMetricsPrerender DISABLED_PageLoadMetricsPrerender
-#else
-#define MAYBE_PageLoadMetricsPrerender PageLoadMetricsPrerender
-#endif
-IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, MAYBE_PageLoadMetricsPrerender) {
+IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PageLoadMetricsPrerender) {
   test_utils::FirstContentfulPaintManagerWaiter* prerender_fcp_waiter =
       test_utils::FirstContentfulPaintManagerWaiter::Create(
           GetPrerenderManager());
@@ -1112,7 +1106,7 @@
   // Histogram logged during the prefetch_loader.html load, but not during the
   // prerender.
   histogram_tester().ExpectTotalCount(
-      "PageLoad.DocumentTiming.NavigationToFirstLayout", 1);
+      "PageLoad.ParseTiming.NavigationToParseStart", 1);
 
   // Histograms only emitted during the simple load which does not happen here
   // (as prefetch_loader.html has an empty body, it does not generate a FCP).
diff --git a/chrome/browser/profiles/profiles_state.cc b/chrome/browser/profiles/profiles_state.cc
index 268c5df..005c922 100644
--- a/chrome/browser/profiles/profiles_state.cc
+++ b/chrome/browser/profiles/profiles_state.cc
@@ -34,6 +34,10 @@
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/gfx/text_elider.h"
 
+#if defined(OS_CHROMEOS)
+#include "chromeos/login/login_state.h"
+#endif
+
 namespace profiles {
 
 bool IsMultipleProfilesEnabled() {
@@ -279,4 +283,13 @@
   return at_least_one_regular_profile_present;
 }
 
+bool IsPublicSession() {
+#if defined(OS_CHROMEOS)
+  if (chromeos::LoginState::IsInitialized()) {
+    return chromeos::LoginState::Get()->IsPublicSessionUser();
+  }
+#endif
+  return false;
+}
+
 }  // namespace profiles
diff --git a/chrome/browser/profiles/profiles_state.h b/chrome/browser/profiles/profiles_state.h
index 758b649b..d97a6c8 100644
--- a/chrome/browser/profiles/profiles_state.h
+++ b/chrome/browser/profiles/profiles_state.h
@@ -108,6 +108,9 @@
 // and they are all locked.
 bool AreAllNonChildNonSupervisedProfilesLocked();
 
+// Returns whether a public session is being run currently.
+bool IsPublicSession();
+
 }  // namespace profiles
 
 #endif  // CHROME_BROWSER_PROFILES_PROFILES_STATE_H_
diff --git a/chrome/browser/search_engines/template_url_scraper_browsertest.cc b/chrome/browser/search_engines/template_url_scraper_browsertest.cc
index 36305e4..fdbf41b 100644
--- a/chrome/browser/search_engines/template_url_scraper_browsertest.cc
+++ b/chrome/browser/search_engines/template_url_scraper_browsertest.cc
@@ -81,10 +81,9 @@
 
   // We need to substract the default pre-populated engines that the profile is
   // set up with.
-  size_t default_index = 0;
   std::vector<std::unique_ptr<TemplateURLData>> prepopulate_urls =
       TemplateURLPrepopulateData::GetPrepopulatedEngines(
-          browser()->profile()->GetPrefs(), &default_index);
+          browser()->profile()->GetPrefs(), nullptr);
 
   EXPECT_EQ(prepopulate_urls.size(), all_urls.size());
 
diff --git a/chrome/browser/search_engines/template_url_service_sync_unittest.cc b/chrome/browser/search_engines/template_url_service_sync_unittest.cc
index 0596b96f..1ad6139 100644
--- a/chrome/browser/search_engines/template_url_service_sync_unittest.cc
+++ b/chrome/browser/search_engines/template_url_service_sync_unittest.cc
@@ -1935,10 +1935,9 @@
 TEST_F(TemplateURLServiceSyncTest, PreSyncUpdates) {
   const char* kNewKeyword = "somethingnew";
   // Fetch the prepopulate search engines so we know what they are.
-  size_t default_search_provider_index = 0;
   std::vector<std::unique_ptr<TemplateURLData>> prepop_turls =
       TemplateURLPrepopulateData::GetPrepopulatedEngines(
-          profile_a()->GetTestingPrefService(), &default_search_provider_index);
+          profile_a()->GetTestingPrefService(), nullptr);
 
   // We have to prematurely exit this test if for some reason this machine does
   // not have any prepopulate TemplateURLs.
diff --git a/chrome/browser/ui/app_list/arc/arc_app_utils.cc b/chrome/browser/ui/app_list/arc/arc_app_utils.cc
index ce01953..52d2401 100644
--- a/chrome/browser/ui/app_list/arc/arc_app_utils.cc
+++ b/chrome/browser/ui/app_list/arc/arc_app_utils.cc
@@ -27,6 +27,23 @@
 #include "ui/display/screen.h"
 #include "ui/events/event_constants.h"
 
+// Helper macro which returns the AppInstance.
+#define GET_APP_INSTANCE(method_name)                                    \
+  (arc::ArcServiceManager::Get()                                         \
+       ? ARC_GET_INSTANCE_FOR_METHOD(                                    \
+             arc::ArcServiceManager::Get()->arc_bridge_service()->app(), \
+             method_name)                                                \
+       : nullptr)
+
+// Helper function which returns the IntentHelperInstance.
+#define GET_INTENT_HELPER_INSTANCE(method_name)                    \
+  (arc::ArcServiceManager::Get()                                   \
+       ? ARC_GET_INSTANCE_FOR_METHOD(arc::ArcServiceManager::Get() \
+                                         ->arc_bridge_service()    \
+                                         ->intent_helper(),        \
+                                     method_name)                  \
+       : nullptr)
+
 namespace arc {
 
 namespace {
@@ -37,68 +54,15 @@
 constexpr int kNexus5Width = 410;
 constexpr int kNexus5Height = 690;
 
-// Minimum required versions.
-constexpr uint32_t kMinVersion = 0;
-constexpr uint32_t kCanHandleResolutionMinVersion = 1;
-constexpr uint32_t kSendBroadcastMinVersion = 1;
-constexpr uint32_t kUninstallPackageMinVersion = 2;
-constexpr uint32_t kTaskSupportMinVersion = 3;
-constexpr uint32_t kShowPackageInfoMinVersion = 5;
-constexpr uint32_t kRemoveIconMinVersion = 9;
-constexpr uint32_t kShowPackageInfoOnPageMinVersion = 10;
-
-// Service name strings.
-constexpr char kCanHandleResolutionStr[] = "get resolution capability";
-constexpr char kCloseTaskStr[] = "close task";
-constexpr char kLaunchAppStr[] = "launch app";
-constexpr char kRemoveIconStr[] = "remove icon";
-constexpr char kSetActiveTaskStr[] = "set active task";
-constexpr char kShowPackageInfoStr[] = "show package info";
-constexpr char kUninstallPackageStr[] = "uninstall package";
-
 // Intent helper strings.
 constexpr char kIntentHelperClassName[] =
     "org.chromium.arc.intent_helper.SettingsReceiver";
 constexpr char kIntentHelperPackageName[] = "org.chromium.arc.intent_helper";
-constexpr char kSendBroadcastStr[] = "SendBroadcast";
 constexpr char kSetInTouchModeIntent[] =
     "org.chromium.arc.intent_helper.SET_IN_TOUCH_MODE";
 constexpr char kShowTalkbackSettingsIntent[] =
     "org.chromium.arc.intent_helper.SHOW_TALKBACK_SETTINGS";
 
-// Helper function which returns the AppInstance. Create related logs when error
-// happens.
-arc::mojom::AppInstance* GetAppInstance(uint32_t required_version,
-                                        const std::string& service_name) {
-  auto* arc_service_manager = arc::ArcServiceManager::Get();
-  if (!arc_service_manager) {
-    VLOG(2) << "Request to " << service_name
-            << " when bridge service is not ready.";
-    return nullptr;
-  }
-
-  return arc_service_manager->arc_bridge_service()
-      ->app()
-      ->GetInstanceForVersion(required_version, service_name.c_str());
-}
-
-// Helper function which returns the IntentHelperInstance. Create related logs
-// when error happens.
-arc::mojom::IntentHelperInstance* GetIntentHelperInstance(
-    uint32_t required_version,
-    const std::string& service_name) {
-  auto* arc_service_manager = arc::ArcServiceManager::Get();
-  if (!arc_service_manager) {
-    VLOG(2) << "Request to " << service_name
-            << " when bridge service is not ready.";
-    return nullptr;
-  }
-
-  return arc_service_manager->arc_bridge_service()
-      ->intent_helper()
-      ->GetInstanceForVersion(required_version, service_name.c_str());
-}
-
 void PrioritizeArcInstanceCallback(bool success) {
   VLOG(2) << "Finished prioritizing the instance: result=" << success;
   if (!success)
@@ -243,13 +207,12 @@
     return false;
   }
 
-  arc::mojom::AppInstance* app_instance =
-      GetAppInstance(kMinVersion, kLaunchAppStr);
+  arc::mojom::AppInstance* app_instance = GET_APP_INSTANCE(LaunchApp);
   if (!app_instance)
     return false;
 
   arc::mojom::IntentHelperInstance* intent_helper_instance =
-      GetIntentHelperInstance(kSendBroadcastMinVersion, kSendBroadcastStr);
+      GET_INTENT_HELPER_INSTANCE(SendBroadcast);
   if (intent_helper_instance) {
     base::DictionaryValue extras;
     extras.SetBoolean("inTouchMode", IsMouseOrTouchEventFromFlags(event_flags));
@@ -261,6 +224,10 @@
   }
 
   if (app_info->shortcut) {
+    // Before calling LaunchIntent, check if the interface is supported. Reusing
+    // the same |app_instance| for LaunchIntent is allowed.
+    if (!GET_APP_INSTANCE(LaunchIntent))
+      return false;
     app_instance->LaunchIntent(app_info->intent_uri, target_rect);
   } else {
     app_instance->LaunchApp(app_info->package_name, app_info->activity,
@@ -342,16 +309,14 @@
 }
 
 void SetTaskActive(int task_id) {
-  arc::mojom::AppInstance* app_instance =
-      GetAppInstance(kTaskSupportMinVersion, kSetActiveTaskStr);
+  arc::mojom::AppInstance* app_instance = GET_APP_INSTANCE(SetTaskActive);
   if (!app_instance)
     return;
   app_instance->SetTaskActive(task_id);
 }
 
 void CloseTask(int task_id) {
-  arc::mojom::AppInstance* app_instance =
-      GetAppInstance(kTaskSupportMinVersion, kCloseTaskStr);
+  arc::mojom::AppInstance* app_instance = GET_APP_INSTANCE(CloseTask);
   if (!app_instance)
     return;
   app_instance->CloseTask(task_id);
@@ -359,7 +324,7 @@
 
 void ShowTalkBackSettings() {
   arc::mojom::IntentHelperInstance* intent_helper_instance =
-      GetIntentHelperInstance(kSendBroadcastMinVersion, kSendBroadcastStr);
+      GET_INTENT_HELPER_INSTANCE(SendBroadcast);
   if (!intent_helper_instance)
     return;
 
@@ -381,8 +346,7 @@
     return false;
   }
 
-  arc::mojom::AppInstance* app_instance =
-      GetAppInstance(kCanHandleResolutionMinVersion, kCanHandleResolutionStr);
+  arc::mojom::AppInstance* app_instance = GET_APP_INSTANCE(CanHandleResolution);
   if (!app_instance)
     return false;
 
@@ -394,8 +358,7 @@
 void UninstallPackage(const std::string& package_name) {
   VLOG(2) << "Uninstalling " << package_name;
 
-  arc::mojom::AppInstance* app_instance =
-      GetAppInstance(kUninstallPackageMinVersion, kUninstallPackageStr);
+  arc::mojom::AppInstance* app_instance = GET_APP_INSTANCE(UninstallPackage);
   if (!app_instance)
     return;
 
@@ -421,8 +384,7 @@
 void RemoveCachedIcon(const std::string& icon_resource_id) {
   VLOG(2) << "Removing icon " << icon_resource_id;
 
-  arc::mojom::AppInstance* app_instance =
-      GetAppInstance(kRemoveIconMinVersion, kRemoveIconStr);
+  arc::mojom::AppInstance* app_instance = GET_APP_INSTANCE(RemoveCachedIcon);
   if (!app_instance)
     return;
 
@@ -434,7 +396,7 @@
   VLOG(2) << "Showing package info for " << package_name;
 
   arc::mojom::AppInstance* app_instance =
-      GetAppInstance(kShowPackageInfoMinVersion, kShowPackageInfoStr);
+      GET_APP_INSTANCE(ShowPackageInfoDeprecated);
   if (!app_instance)
     return false;
 
@@ -448,7 +410,7 @@
   VLOG(2) << "Showing package info for " << package_name;
 
   arc::mojom::AppInstance* app_instance =
-      GetAppInstance(kShowPackageInfoOnPageMinVersion, kShowPackageInfoStr);
+      GET_APP_INSTANCE(ShowPackageInfoOnPage);
   if (!app_instance)
     return false;
 
diff --git a/chrome/browser/ui/cocoa/extensions/browser_actions_container_view.mm b/chrome/browser/ui/cocoa/extensions/browser_actions_container_view.mm
index 3bf1e04..97ed1a6 100644
--- a/chrome/browser/ui/cocoa/extensions/browser_actions_container_view.mm
+++ b/chrome/browser/ui/cocoa/extensions/browser_actions_container_view.mm
@@ -7,7 +7,6 @@
 #include <algorithm>
 #include <utility>
 
-#import "chrome/browser/ui/cocoa/l10n_util.h"
 #import "chrome/browser/ui/cocoa/view_id_util.h"
 #include "ui/base/cocoa/appkit_utils.h"
 #include "ui/events/keycodes/keyboard_code_conversion_mac.h"
@@ -59,9 +58,6 @@
 - (id)initWithFrame:(NSRect)frameRect {
   if ((self = [super initWithFrame:frameRect])) {
     grippyRect_ = NSMakeRect(0.0, 0.0, kGrippyWidth, NSHeight([self bounds]));
-    if (cocoa_l10n_util::ShouldDoExperimentalRTLLayout())
-      grippyRect_.origin.x = NSWidth(frameRect) - NSWidth(grippyRect_);
-
     canDragLeft_ = YES;
     canDragRight_ = YES;
     resizable_ = YES;
@@ -166,8 +162,6 @@
 }
 
 - (void)resetCursorRects {
-  if (cocoa_l10n_util::ShouldDoExperimentalRTLLayout())
-    grippyRect_.origin.x = NSWidth([self frame]) - NSWidth(grippyRect_);
   [self addCursorRect:grippyRect_ cursor:[self appropriateCursorForGrippy]];
 }
 
@@ -220,29 +214,23 @@
   NSRect containerFrame = [self frame];
   CGFloat dX = [theEvent deltaX];
   CGFloat withDelta = location.x - dX;
-  BOOL isRTL = cocoa_l10n_util::ShouldDoExperimentalRTLLayout();
-
+  canDragRight_ = (withDelta >= initialDragPoint_.x) &&
+      (NSWidth(containerFrame) > kMinimumContainerWidth);
   CGFloat maxAllowedWidth = [self maxAllowedWidth];
+  containerFrame.size.width =
+      std::max(NSWidth(containerFrame) - dX, kMinimumContainerWidth);
+  canDragLeft_ = withDelta <= initialDragPoint_.x &&
+      NSWidth(containerFrame) < maxDesiredWidth_ &&
+      NSWidth(containerFrame) < maxAllowedWidth;
 
-  const CGFloat maxWidth = std::min(maxAllowedWidth, maxDesiredWidth_);
-  CGFloat newWidth = NSWidth(containerFrame) + (isRTL ? dX : -dX);
-  newWidth = std::min(std::max(newWidth, kMinimumContainerWidth), maxWidth);
-
-  BOOL canGrow = NSWidth(containerFrame) < maxWidth;
-  BOOL canShrink = NSWidth(containerFrame) > kMinimumContainerWidth;
-
-  canDragLeft_ =
-      withDelta <= initialDragPoint_.x && (isRTL ? canShrink : canGrow);
-  canDragRight_ =
-      (withDelta >= initialDragPoint_.x) && (isRTL ? canGrow : canShrink);
-  if ((dX < 0.0 && !canDragLeft_) || (dX > 0.0 && !canDragRight_) ||
-      fabs(dX) < FLT_EPSILON)
+  if ((dX < 0.0 && !canDragLeft_) || (dX > 0.0 && !canDragRight_))
     return;
 
-  grippyPinned_ = newWidth >= maxAllowedWidth;
-  if (!isRTL)
-    containerFrame.origin.x += dX;
-  containerFrame.size.width = newWidth;
+  if (NSWidth(containerFrame) <= kMinimumContainerWidth)
+    return;
+
+  grippyPinned_ = NSWidth(containerFrame) >= maxAllowedWidth;
+  containerFrame.origin.x += dX;
 
   [self setFrame:containerFrame];
   [self setNeedsDisplay:YES];
@@ -283,18 +271,14 @@
 
 - (void)resizeToWidth:(CGFloat)width animate:(BOOL)animate {
   width = std::max(width, kMinimumContainerWidth);
-  NSRect newFrame = [self frame];
+  NSRect frame = [self frame];
 
   CGFloat maxAllowedWidth = [self maxAllowedWidth];
   width = std::min(maxAllowedWidth, width);
 
-  if (cocoa_l10n_util::ShouldDoExperimentalRTLLayout()) {
-    newFrame.size.width = width;
-  } else {
-    CGFloat dX = NSWidth(newFrame) - width;
-    newFrame.size.width = width;
-    newFrame.origin.x += dX;
-  }
+  CGFloat dX = frame.size.width - width;
+  frame.size.width = width;
+  NSRect newFrame = NSOffsetRect(frame, dX, 0);
 
   grippyPinned_ = width == maxAllowedWidth;
 
diff --git a/chrome/browser/ui/cocoa/extensions/browser_actions_controller.mm b/chrome/browser/ui/cocoa/extensions/browser_actions_controller.mm
index 60d3c42..44b5cbc1 100644
--- a/chrome/browser/ui/cocoa/extensions/browser_actions_controller.mm
+++ b/chrome/browser/ui/cocoa/extensions/browser_actions_controller.mm
@@ -20,7 +20,6 @@
 #import "chrome/browser/ui/cocoa/extensions/extension_popup_controller.h"
 #import "chrome/browser/ui/cocoa/extensions/toolbar_actions_bar_bubble_mac.h"
 #import "chrome/browser/ui/cocoa/image_button_cell.h"
-#import "chrome/browser/ui/cocoa/l10n_util.h"
 #import "chrome/browser/ui/cocoa/menu_button.h"
 #import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h"
 #include "chrome/browser/ui/extensions/extension_message_bubble_bridge.h"
@@ -582,14 +581,11 @@
     if (NSMinX([button frameAfterAnimation]) == NSMinX(buttonFrame))
       continue;
 
-    // In LTR, We set the x-origin by calculating the proper distance from the
-    // right edge in the container so that, if the container is animating, the
+    // We set the x-origin by calculating the proper distance from the right
+    // edge in the container so that, if the container is animating, the
     // button appears stationary.
-    if (!cocoa_l10n_util::ShouldDoExperimentalRTLLayout()) {
-      buttonFrame.origin.x = NSWidth([containerView_ frame]) -
-                             (toolbarActionsBar_->GetPreferredSize().width() -
-                              NSMinX(buttonFrame));
-    }
+    buttonFrame.origin.x = NSWidth([containerView_ frame]) -
+        (toolbarActionsBar_->GetPreferredSize().width() - NSMinX(buttonFrame));
     [button setFrame:buttonFrame animate:NO];
   }
 }
@@ -787,16 +783,9 @@
 }
 
 - (void)updateGrippyCursors {
-  BOOL canClose = [self visibleButtonCount] > 0;
-  BOOL canOpen = toolbarActionsBar_->GetIconCount() != [buttons_ count];
   [containerView_
-      setCanDragLeft:cocoa_l10n_util::ShouldDoExperimentalRTLLayout()
-                         ? canClose
-                         : canOpen];
-  [containerView_
-      setCanDragRight:cocoa_l10n_util::ShouldDoExperimentalRTLLayout()
-                          ? canOpen
-                          : canClose];
+      setCanDragLeft:toolbarActionsBar_->GetIconCount() != [buttons_ count]];
+  [containerView_ setCanDragRight:[self visibleButtonCount] > 0];
   [[containerView_ window] invalidateCursorRectsForView:containerView_];
 }
 
diff --git a/chrome/browser/ui/cocoa/toolbar/toolbar_controller.h b/chrome/browser/ui/cocoa/toolbar/toolbar_controller.h
index 732485ee..316a89f9 100644
--- a/chrome/browser/ui/cocoa/toolbar/toolbar_controller.h
+++ b/chrome/browser/ui/cocoa/toolbar/toolbar_controller.h
@@ -200,10 +200,6 @@
 - (void)installAppMenu;
 // Return a hover button for the current event.
 - (NSButton*)hoverButtonForEvent:(NSEvent*)theEvent;
-// Adjusts browser actions container view in response to toolbar frame changes.
-// Outside of tests, called in response to frame changed/new window
-// notifications.
-- (void)toolbarFrameChanged;
 @end
 
 #endif  // CHROME_BROWSER_UI_COCOA_TOOLBAR_TOOLBAR_CONTROLLER_H_
diff --git a/chrome/browser/ui/cocoa/toolbar/toolbar_controller.mm b/chrome/browser/ui/cocoa/toolbar/toolbar_controller.mm
index 0d52daf..73ce5ce8 100644
--- a/chrome/browser/ui/cocoa/toolbar/toolbar_controller.mm
+++ b/chrome/browser/ui/cocoa/toolbar/toolbar_controller.mm
@@ -36,7 +36,6 @@
 #import "chrome/browser/ui/cocoa/extensions/browser_actions_controller.h"
 #import "chrome/browser/ui/cocoa/gradient_button_cell.h"
 #import "chrome/browser/ui/cocoa/image_button_cell.h"
-#import "chrome/browser/ui/cocoa/l10n_util.h"
 #import "chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_editor.h"
 #import "chrome/browser/ui/cocoa/location_bar/location_bar_decoration.h"
 #import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h"
@@ -146,9 +145,8 @@
 // Height of the location bar. Used for animating the toolbar in and out when
 // the location bar is displayed stand-alone for bookmark apps.
 + (CGFloat)locationBarHeight;
-// Return the amount of horizontal padding that the app menu should have on
-// each side.
-+ (CGFloat)appMenuPadding;
+// Return the amount of left padding that the app menu should have.
++ (CGFloat)appMenuLeftPadding;
 - (void)cleanUp;
 - (void)addAccessibilityDescriptions;
 - (void)initCommandStatus:(CommandUpdater*)commands;
@@ -158,7 +156,7 @@
 - (CGFloat)baseToolbarHeight;
 - (void)toolbarFrameChanged;
 - (void)showLocationBarOnly;
-- (void)pinLocationBarBeforeBrowserActionsContainerAndAnimate:(BOOL)animate;
+- (void)pinLocationBarToLeftOfBrowserActionsContainerAndAnimate:(BOOL)animate;
 - (void)maintainMinimumLocationBarWidth;
 - (void)adjustBrowserActionsContainerForNewWindow:(NSNotification*)notification;
 - (void)browserActionsContainerDragged:(NSNotification*)notification;
@@ -238,7 +236,7 @@
   return kLocationBarHeight;
 }
 
-+ (CGFloat)appMenuPadding {
++ (CGFloat)appMenuLeftPadding {
   return kElementPadding;
 }
 
@@ -299,14 +297,6 @@
     return;
   }
 
-  BOOL isRTL = cocoa_l10n_util::ShouldDoExperimentalRTLLayout();
-  NSAutoresizingMaskOptions leadingButtonMask =
-      isRTL ? NSViewMinXMargin | NSViewMinYMargin
-            : NSViewMaxXMargin | NSViewMinYMargin;
-  NSAutoresizingMaskOptions trailingButtonMask =
-      isRTL ? NSViewMaxXMargin | NSViewMinYMargin
-            : NSViewMinXMargin | NSViewMinYMargin;
-
   // Make Material Design layout adjustments to the NIB items.
   ToolbarView* toolbarView = [self toolbarView];
   NSRect toolbarBounds = [toolbarView bounds];
@@ -317,24 +307,30 @@
   frame.size.height = [self baseToolbarHeight];
   [toolbarView setFrame:frame];
 
-  NSArray* leadingButtons =
-      @[ backButton_, forwardButton_, reloadButton_, homeButton_ ];
-  const CGFloat xStart = kElementPadding + kButtonInset;
-  const CGFloat xOffset = toolbarButtonSize.width + kButtonInset * 2;
-  const CGFloat yPosition =
+  NSRect backButtonFrame = [backButton_ frame];
+  backButtonFrame.origin.x = kElementPadding + kButtonInset;
+  backButtonFrame.origin.y =
       NSMaxY(toolbarBounds) - kElementPadding - toolbarButtonSize.height;
-  for (NSUInteger i = 0; i < [leadingButtons count]; i++) {
-    NSButton* button = leadingButtons[i];
-    NSRect buttonFrame = [button frame];
-    buttonFrame.size = toolbarButtonSize;
-    buttonFrame.origin.y = yPosition;
-    const CGFloat xPosition = xStart + i * xOffset;
-    buttonFrame.origin.x =
-        isRTL ? NSWidth(frame) - toolbarButtonSize.width - xPosition
-              : xPosition;
-    [button setFrame:buttonFrame];
-    [button setAutoresizingMask:leadingButtonMask];
-  }
+  backButtonFrame.size = toolbarButtonSize;
+  [backButton_ setFrame:backButtonFrame];
+
+  NSRect forwardButtonFrame = [forwardButton_ frame];
+  forwardButtonFrame.origin.x = NSMaxX(backButtonFrame) + 2 * kButtonInset;
+  forwardButtonFrame.origin.y = backButtonFrame.origin.y;
+  forwardButtonFrame.size = toolbarButtonSize;
+  [forwardButton_ setFrame:forwardButtonFrame];
+
+  NSRect reloadButtonFrame = [reloadButton_ frame];
+  reloadButtonFrame.origin.x = NSMaxX(forwardButtonFrame) + 2 * kButtonInset;
+  reloadButtonFrame.origin.y = forwardButtonFrame.origin.y;
+  reloadButtonFrame.size = toolbarButtonSize;
+  [reloadButton_ setFrame:reloadButtonFrame];
+
+  NSRect homeButtonFrame = [homeButton_ frame];
+  homeButtonFrame.origin.x = NSMaxX(reloadButtonFrame) + 2 * kButtonInset;
+  homeButtonFrame.origin.y = reloadButtonFrame.origin.y;
+  homeButtonFrame.size = toolbarButtonSize;
+  [homeButton_ setFrame:homeButtonFrame];
 
   // Replace the app button from the nib with an AppToolbarButton instance for
   // Material Design.
@@ -348,41 +344,27 @@
 
   // Adjust the menu button's position.
   NSRect menuButtonFrame = [appMenuButton_ frame];
-  if (isRTL) {
-    menuButtonFrame.origin.x = [ToolbarController appMenuPadding];
-  } else {
-    CGFloat menuButtonFrameMaxX =
-        NSMaxX(toolbarBounds) - [ToolbarController appMenuPadding];
-    menuButtonFrame.origin.x =
-        menuButtonFrameMaxX - kButtonInset - toolbarButtonSize.width;
-  }
-  menuButtonFrame.origin.y = yPosition;
+  CGFloat menuButtonFrameMaxX =
+      NSMaxX(toolbarBounds) - [ToolbarController appMenuLeftPadding];
+  menuButtonFrame.origin.x =
+      menuButtonFrameMaxX - kButtonInset - toolbarButtonSize.width;
+  menuButtonFrame.origin.y = homeButtonFrame.origin.y;
   menuButtonFrame.size = toolbarButtonSize;
   [appMenuButton_ setFrame:menuButtonFrame];
-  [appMenuButton_ setAutoresizingMask:trailingButtonMask];
 
   // Adjust the size and location on the location bar to take up the
   // space between the reload and menu buttons.
   NSRect locationBarFrame = [locationBar_ frame];
-  locationBarFrame.origin.x = isRTL
-                                  ? NSMaxX(menuButtonFrame) + kButtonInset
-                                  : NSMaxX([homeButton_ frame]) + kButtonInset;
-  if (![homeButton_ isHidden] && !isRTL) {
-    // Ensure proper spacing between the home button and location bar
+  locationBarFrame.origin.x = NSMaxX(homeButtonFrame) + kButtonInset;
+  if (![homeButton_ isHidden]) {
+    // Ensure proper spacing between the home button and the location bar.
     locationBarFrame.origin.x += kElementPadding;
   }
   locationBarFrame.origin.y =
       NSMaxY(toolbarBounds) - kLocationBarPadding - kLocationBarHeight;
-  CGFloat rightEdge = 0;
-  if (isRTL) {
-    rightEdge = NSMinX([homeButton_ frame]) - kButtonInset;
-    if (![homeButton_ isHidden])
-      rightEdge -= kElementPadding;
-  } else {
-    rightEdge = NSMinX(menuButtonFrame);
-  }
-  locationBarFrame.size.width = rightEdge - NSMinX(locationBarFrame);
-
+  locationBarFrame.size.width =
+      menuButtonFrame.origin.x -
+          locationBarFrame.origin.x;
   locationBarFrame.size.height = kLocationBarHeight;
   [locationBar_ setFrame:locationBarFrame];
 
@@ -391,10 +373,7 @@
   containerFrame.size.width += kButtonInset;
   containerFrame.origin.y = locationBarFrame.origin.y + kContainerYOffset;
   containerFrame.size.height = toolbarButtonSize.height;
-  if (cocoa_l10n_util::ShouldDoExperimentalRTLLayout())
-    containerFrame.origin.x = NSMinX(locationBarFrame);
   [browserActionsContainerView_ setFrame:containerFrame];
-  [browserActionsContainerView_ setAutoresizingMask:trailingButtonMask];
 
   notificationBridge_.reset(
       new ToolbarControllerInternal::NotificationBridge(self));
@@ -441,7 +420,7 @@
   [self showOptionalHomeButton];
   [self installAppMenu];
 
-  [self pinLocationBarBeforeBrowserActionsContainerAndAnimate:NO];
+  [self pinLocationBarToLeftOfBrowserActionsContainerAndAnimate:NO];
 
   // Create the controllers for the back/forward menus.
   backMenuController_.reset([[BackForwardMenuController alloc]
@@ -709,7 +688,7 @@
 
 - (id)customFieldEditorForObject:(id)obj {
   if (obj == locationBar_) {
-    // Lazily construct Field editor, Cocoa UI code always runs on the
+    // Lazilly construct Field editor, Cocoa UI code always runs on the
     // same thread, so there shoudn't be a race condition here.
     if (autocompleteTextFieldEditor_.get() == nil) {
       autocompleteTextFieldEditor_.reset(
@@ -725,12 +704,20 @@
   return nil;
 }
 
-// Returns an array of views, ordered leading to trailing.
+// Returns an array of views in the order of the outlets above.
 - (NSArray*)toolbarViews {
-  return @[
-    backButton_, forwardButton_, reloadButton_, homeButton_, locationBar_,
-    browserActionsContainerView_, appMenuButton_
-  ];
+  return [NSArray arrayWithObjects:backButton_, forwardButton_, reloadButton_,
+                                   homeButton_, appMenuButton_, locationBar_,
+                                   browserActionsContainerView_, nil];
+}
+
+// Moves |rect| to the right by |delta|, keeping the right side fixed by
+// shrinking the width to compensate. Passing a negative value for |deltaX|
+// moves to the left and increases the width.
+- (NSRect)adjustRect:(NSRect)rect byAmount:(CGFloat)deltaX {
+  NSRect frame = NSOffsetRect(rect, deltaX, 0);
+  frame.size.width -= deltaX;
+  return frame;
 }
 
 // Show or hide the home button based on the pref.
@@ -750,11 +737,9 @@
   moveX += kElementPadding;
   if (hide)
     moveX *= -1;  // Reverse the direction of the move.
-  CGRect locationBarFrame = [locationBar_ frame];
-  locationBarFrame.size.width -= moveX;
-  if (!cocoa_l10n_util::ShouldDoExperimentalRTLLayout())
-    locationBarFrame.origin.x += moveX;
-  [locationBar_ setFrame:locationBarFrame];
+
+  [locationBar_ setFrame:[self adjustRect:[locationBar_ frame]
+                                 byAmount:moveX]];
   [homeButton_ setHidden:hide];
 }
 
@@ -815,7 +800,7 @@
              object:[[self view] window]];
   }
   if (![browserActionsContainerView_ isHidden])
-    [self pinLocationBarBeforeBrowserActionsContainerAndAnimate:NO];
+    [self pinLocationBarToLeftOfBrowserActionsContainerAndAnimate:NO];
 }
 
 - (void)updateVisibility:(BOOL)visible withAnimation:(BOOL)animate {
@@ -841,41 +826,34 @@
 }
 
 - (void)browserActionsContainerDragged:(NSNotification*)notification {
-  [self pinLocationBarBeforeBrowserActionsContainerAndAnimate:NO];
+  [self pinLocationBarToLeftOfBrowserActionsContainerAndAnimate:NO];
 }
 
 - (void)browserActionsVisibilityChanged:(NSNotification*)notification {
-  [self pinLocationBarBeforeBrowserActionsContainerAndAnimate:NO];
+  [self pinLocationBarToLeftOfBrowserActionsContainerAndAnimate:NO];
 }
 
 - (void)browserActionsContainerWillAnimate:(NSNotification*)notification {
-  [self pinLocationBarBeforeBrowserActionsContainerAndAnimate:YES];
+  [self pinLocationBarToLeftOfBrowserActionsContainerAndAnimate:YES];
 }
 
-- (void)pinLocationBarBeforeBrowserActionsContainerAndAnimate:(BOOL)animate {
-  CGFloat delta = 0.0;
-  if (cocoa_l10n_util::ShouldDoExperimentalRTLLayout()) {
-    CGFloat leftEdge = NSMinX([locationBar_ frame]);
-    if ([browserActionsContainerView_ isHidden]) {
-      delta = leftEdge - NSMaxX([appMenuButton_ frame]) +
-              [ToolbarController appMenuPadding] + kButtonInset;
-    } else {
-      delta = leftEdge - NSMaxX([browserActionsContainerView_ frame]) +
-              kButtonInset;
-    }
-  } else {
-    CGFloat rightEdge = NSMaxX([locationBar_ frame]);
-    if ([browserActionsContainerView_ isHidden]) {
-      delta = NSMinX([appMenuButton_ frame]) -
-              [ToolbarController appMenuPadding] - kButtonInset - rightEdge;
-    } else {
-      delta = NSMinX([browserActionsContainerView_ frame]) - kButtonInset -
-              rightEdge;
-    }
-  }
+- (void)pinLocationBarToLeftOfBrowserActionsContainerAndAnimate:(BOOL)animate {
+  CGFloat locationBarXPos = NSMaxX([locationBar_ frame]);
+  CGFloat leftDistance = 0.0;
 
-  if (delta != 0.0)
-    [self adjustLocationSizeBy:delta animate:animate];
+  if ([browserActionsContainerView_ isHidden]) {
+    CGFloat edgeXPos = [appMenuButton_ frame].origin.x;
+    leftDistance = edgeXPos - locationBarXPos -
+        [ToolbarController appMenuLeftPadding] - kButtonInset;
+  } else {
+    leftDistance = NSMinX([browserActionsContainerView_ animationEndFrame]) -
+        locationBarXPos;
+    // Equalize the distance between the location bar and the first extension
+    // button, and the distance between the location bar and home/reload button.
+    leftDistance -= kButtonInset;
+  }
+  if (leftDistance != 0.0)
+    [self adjustLocationSizeBy:leftDistance animate:animate];
   else
     [locationBar_ stopAnimation];
 }
@@ -905,7 +883,7 @@
     NSRect containerFrame = [browserActionsContainerView_ frame];
     containerFrame.origin.y = [locationBar_ frame].origin.y + kContainerYOffset;
     [browserActionsContainerView_ setFrame:containerFrame];
-    [self pinLocationBarBeforeBrowserActionsContainerAndAnimate:NO];
+    [self pinLocationBarToLeftOfBrowserActionsContainerAndAnimate:NO];
   }
 
   [self maintainMinimumLocationBarWidth];
@@ -916,13 +894,9 @@
     NSRect containerFrame = [browserActionsContainerView_ frame];
     // Determine how much the container needs to move in case it's overlapping
     // with the location bar.
-    if (cocoa_l10n_util::ShouldDoExperimentalRTLLayout()) {
-      CGFloat dX = NSMaxX(containerFrame) - NSMinX([locationBar_ frame]);
-      containerFrame.size.width -= dX;
-    } else {
-      CGFloat dX = NSMaxX([locationBar_ frame]) - containerFrame.origin.x;
-      containerFrame = NSOffsetRect(containerFrame, dX, 0);
-    }
+    CGFloat dX = NSMaxX([locationBar_ frame]) - containerFrame.origin.x;
+    containerFrame = NSOffsetRect(containerFrame, dX, 0);
+    containerFrame.size.width -= dX;
     [browserActionsContainerView_ setFrame:containerFrame];
   } else if (!locationBarAtMinSize_ &&
       [browserActionsContainerView_ grippyPinned]) {
@@ -932,21 +906,18 @@
     CGFloat dX = NSWidth([locationBar_ frame]) -
         (kMinimumLocationBarWidth + 0.1);
     NSRect containerFrame = [browserActionsContainerView_ frame];
-    if (!cocoa_l10n_util::ShouldDoExperimentalRTLLayout())
-      containerFrame = NSOffsetRect(containerFrame, -dX, 0);
+    containerFrame = NSOffsetRect(containerFrame, -dX, 0);
     containerFrame.size.width += dX;
     CGFloat savedContainerWidth =
         [browserActionsController_ preferredSize].width();
     if (NSWidth(containerFrame) >= savedContainerWidth) {
-      if (!cocoa_l10n_util::ShouldDoExperimentalRTLLayout()) {
-        containerFrame = NSOffsetRect(
-            containerFrame, NSWidth(containerFrame) - savedContainerWidth, 0);
-      }
+      containerFrame = NSOffsetRect(containerFrame,
+          NSWidth(containerFrame) - savedContainerWidth, 0);
       containerFrame.size.width = savedContainerWidth;
       [browserActionsContainerView_ setGrippyPinned:NO];
     }
     [browserActionsContainerView_ setFrame:containerFrame];
-    [self pinLocationBarBeforeBrowserActionsContainerAndAnimate:NO];
+    [self pinLocationBarToLeftOfBrowserActionsContainerAndAnimate:NO];
   }
 }
 
@@ -974,17 +945,15 @@
   [reloadButton_ setHidden:YES];
   [appMenuButton_ setHidden:YES];
   [homeButton_ setHidden:YES];
-  [browserActionsContainerView_ setHidden:YES];
 }
 
 - (void)adjustLocationSizeBy:(CGFloat)dX animate:(BOOL)animate {
   // Ensure that the location bar is in its proper place.
   NSRect locationFrame = [locationBar_ frame];
   locationFrame.size.width += dX;
-  if (cocoa_l10n_util::ShouldDoExperimentalRTLLayout())
-    locationFrame.origin.x -= dX;
 
   [locationBar_ stopAnimation];
+
   if (animate)
     [locationBar_ animateToFrame:locationFrame];
   else
diff --git a/chrome/browser/ui/cocoa/toolbar/toolbar_controller_unittest.mm b/chrome/browser/ui/cocoa/toolbar/toolbar_controller_unittest.mm
index 01b22da..d8217085 100644
--- a/chrome/browser/ui/cocoa/toolbar/toolbar_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/toolbar/toolbar_controller_unittest.mm
@@ -4,34 +4,25 @@
 
 #import <Cocoa/Cocoa.h>
 
-#include "base/command_line.h"
 #import "base/mac/scoped_nsobject.h"
 #include "base/macros.h"
 #include "base/run_loop.h"
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/browser/command_updater.h"
-#include "chrome/browser/extensions/extension_action_test_util.h"
-#include "chrome/browser/extensions/extension_service.h"
-#include "chrome/browser/extensions/test_extension_system.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_command_controller.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/browser_list_observer.h"
 #import "chrome/browser/ui/cocoa/image_button_cell.h"
-#import "chrome/browser/ui/cocoa/extensions/browser_actions_controller.h"
 #import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h"
 #import "chrome/browser/ui/cocoa/location_bar/translate_decoration.h"
 #include "chrome/browser/ui/cocoa/test/cocoa_profile_test.h"
-#include "chrome/browser/ui/cocoa/test/scoped_force_rtl_mac.h"
 #import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h"
-#include "chrome/browser/ui/toolbar/toolbar_actions_bar.h"
-#include "chrome/browser/ui/toolbar/toolbar_actions_model.h"
 #import "chrome/browser/ui/cocoa/view_resizer_pong.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/prefs/pref_service.h"
-#include "extensions/browser/extension_system.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #import "testing/gtest_mac.h"
 #include "testing/platform_test.h"
@@ -83,37 +74,14 @@
   // Indexes that match the ordering returned by the private ToolbarController
   // |-toolbarViews| method.
   enum SubviewIndex {
-    kBackIndex,
-    kForwardIndex,
-    kReloadIndex,
-    kHomeIndex,
-    kLocationIndex,
-    kBrowserActionContainerViewIndex,
-    kAppMenuIndex
+    kBackIndex, kForwardIndex, kReloadIndex, kHomeIndex,
+    kAppMenuIndex, kLocationIndex, kBrowserActionContainerViewIndex
   };
 
   void SetUp() override {
     CocoaProfileTest::SetUp();
     ASSERT_TRUE(browser());
 
-    // Add an extension so the browser action container view
-    // is visible and has a real size/position.
-    extensions::TestExtensionSystem* extension_system =
-        static_cast<extensions::TestExtensionSystem*>(
-            extensions::ExtensionSystem::Get(profile()));
-    extension_system->CreateExtensionService(
-        base::CommandLine::ForCurrentProcess(), base::FilePath(), false);
-    scoped_refptr<const extensions::Extension> extension =
-        extensions::extension_action_test_util::CreateActionExtension(
-            "ABC", extensions::extension_action_test_util::BROWSER_ACTION);
-    extensions::ExtensionSystem::Get(profile())
-        ->extension_service()
-        ->AddExtension(extension.get());
-    ToolbarActionsModel* model =
-        extensions::extension_action_test_util::CreateToolbarModelForProfile(
-            profile());
-    model->SetVisibleIconCount(1);
-
     resizeDelegate_.reset([[ViewResizerPong alloc] init]);
 
     CommandUpdater* updater =
@@ -130,12 +98,6 @@
     EXPECT_TRUE([bar_ view]);
     NSView* parent = [test_window() contentView];
     [parent addSubview:[bar_ view]];
-
-    // Nudge a few things to ensure the browser actions container gets
-    // laid out.
-    [bar_ createBrowserActionButtons];
-    [[bar_ browserActionsController] update];
-    [bar_ toolbarFrameChanged];
   }
 
   void TearDown() override {
@@ -215,7 +177,7 @@
   EXPECT_FALSE([GetSubviewAt(kReloadIndex) isHidden]);
   EXPECT_FALSE([GetSubviewAt(kAppMenuIndex) isHidden]);
   EXPECT_TRUE([GetSubviewAt(kHomeIndex) isHidden]);
-  EXPECT_FALSE([GetSubviewAt(kBrowserActionContainerViewIndex) isHidden]);
+  EXPECT_TRUE([GetSubviewAt(kBrowserActionContainerViewIndex) isHidden]);
 
   // For NO/NO, only the top level toolbar view is hidden.
   [bar_ setHasToolbar:NO hasLocationBar:NO];
@@ -226,7 +188,7 @@
   EXPECT_FALSE([GetSubviewAt(kReloadIndex) isHidden]);
   EXPECT_FALSE([GetSubviewAt(kAppMenuIndex) isHidden]);
   EXPECT_TRUE([GetSubviewAt(kHomeIndex) isHidden]);
-  EXPECT_FALSE([GetSubviewAt(kBrowserActionContainerViewIndex) isHidden]);
+  EXPECT_TRUE([GetSubviewAt(kBrowserActionContainerViewIndex) isHidden]);
 
   // Now test the inescapable state.
   [bar_ setHasToolbar:NO hasLocationBar:YES];
@@ -429,36 +391,6 @@
   [bar_ setView:toolbarView];
 }
 
-// Test that subviews are ordered left to right
-TEST_F(ToolbarControllerTest, ElementOrder) {
-  NSArray* views = [bar_ toolbarViews];
-  for (size_t i = 1; i < [views count]; i++) {
-    NSView* previousSubview = views[i - 1];
-    NSView* subview = views[i];
-    EXPECT_LE(NSMinX([previousSubview frame]), NSMinX([subview frame]));
-  }
-}
-
-class ToolbarControllerRTLTest : public ToolbarControllerTest {
- public:
-  ToolbarControllerRTLTest() {}
-
- private:
-  cocoa_l10n_util::ScopedForceRTLMac rtl_;
-
-  DISALLOW_COPY_AND_ASSIGN(ToolbarControllerRTLTest);
-};
-
-// Test that subviews are ordered right to left
-TEST_F(ToolbarControllerRTLTest, ElementOrder) {
-  NSArray* views = [[[bar_ toolbarViews] reverseObjectEnumerator] allObjects];
-  for (size_t i = 1; i < [views count]; i++) {
-    NSView* previousSubview = views[i - 1];
-    NSView* subview = views[i];
-    EXPECT_LE(NSMinX([previousSubview frame]), NSMinX([subview frame]));
-  }
-}
-
 class BrowserRemovedObserver : public chrome::BrowserListObserver {
  public:
   BrowserRemovedObserver() { BrowserList::AddObserver(this); }
diff --git a/chrome/renderer/content_settings_observer.cc b/chrome/renderer/content_settings_observer.cc
index afbaab3..de57921 100644
--- a/chrome/renderer/content_settings_observer.cc
+++ b/chrome/renderer/content_settings_observer.cc
@@ -57,10 +57,13 @@
   return top_origin.GetURL();
 }
 
+// Allow passing both WebURL and GURL here, so that we can early return without
+// allocating a new backing string if only the default rule matches.
+template <typename URL>
 ContentSetting GetContentSettingFromRules(
     const ContentSettingsForOneType& rules,
     const WebFrame* frame,
-    const GURL& secondary_url) {
+    const URL& secondary_url) {
   ContentSettingsForOneType::const_iterator it;
   // If there is only one rule, it's the default rule and we don't need to match
   // the patterns.
@@ -70,9 +73,10 @@
     return rules[0].setting;
   }
   const GURL& primary_url = GetOriginOrURL(frame);
+  const GURL& secondary_gurl = secondary_url;
   for (it = rules.begin(); it != rules.end(); ++it) {
     if (it->primary_pattern.Matches(primary_url) &&
-        it->secondary_pattern.Matches(secondary_url)) {
+        it->secondary_pattern.Matches(secondary_gurl)) {
       return it->setting;
     }
   }
@@ -251,11 +255,9 @@
       return true;
 
     if (content_setting_rules_) {
-      GURL secondary_url(image_url);
-      allow =
-          GetContentSettingFromRules(content_setting_rules_->image_rules,
-                                     render_frame()->GetWebFrame(),
-                                     secondary_url) != CONTENT_SETTING_BLOCK;
+      allow = GetContentSettingFromRules(content_setting_rules_->image_rules,
+                                         render_frame()->GetWebFrame(),
+                                         image_url) != CONTENT_SETTING_BLOCK;
     }
   }
   if (!allow)
@@ -320,8 +322,7 @@
   if (content_setting_rules_) {
     ContentSetting setting =
         GetContentSettingFromRules(content_setting_rules_->script_rules,
-                                   render_frame()->GetWebFrame(),
-                                   GURL(script_url));
+                                   render_frame()->GetWebFrame(), script_url);
     allow = setting != CONTENT_SETTING_BLOCK;
   }
   return allow || IsWhitelistedForContentSettings();
diff --git a/chrome/test/data/android/payments/basic_card.js b/chrome/test/data/android/payments/basic_card.js
new file mode 100644
index 0000000..ce22014
--- /dev/null
+++ b/chrome/test/data/android/payments/basic_card.js
@@ -0,0 +1,274 @@
+/*
+ * 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.
+ */
+
+/**
+ * Merchant checks for ability to pay using debit cards.
+ */
+function checkBasicDebit() { // eslint-disable-line no-unused-vars
+  try {
+    new PaymentRequest(
+        [{
+          supportedMethods: ['basic-card'],
+          data: {
+            supportedTypes: ['debit'],
+          },
+        }], {
+          total: {
+            label: 'Total',
+            amount: {
+              currency: 'USD',
+              value: '5.00',
+            },
+          },
+        })
+      .canMakePayment()
+      .then(function(result) {
+        print(result);
+      })
+      .catch(function(error) {
+        print(error);
+      });
+  } catch (error) {
+    print(error);
+  }
+}
+
+/**
+ * Merchant checks for ability to pay using "basic-card" with "mastercard" as
+ * the supported network.
+ */
+function checkBasicMasterCard() { // eslint-disable-line no-unused-vars
+  try {
+    new PaymentRequest(
+        [{
+          supportedMethods: ['basic-card'],
+          data: {
+            supportedNetworks: ['mastercard'],
+          },
+        }], {
+          total: {
+            label: 'Total',
+            amount: {
+              currency: 'USD',
+              value: '5.00',
+            },
+          },
+        })
+      .canMakePayment()
+      .then(function(result) {
+        print(result);
+      })
+      .catch(function(error) {
+        print(error);
+      });
+  } catch (error) {
+    print(error);
+  }
+}
+
+/**
+ * Merchant checks for ability to pay using "basic-card" with "visa" as the
+ * supported network.
+ */
+function checkBasicVisa() { // eslint-disable-line no-unused-vars
+  try {
+    new PaymentRequest(
+        [{
+          supportedMethods: ['basic-card'],
+          data: {
+            supportedNetworks: ['visa'],
+          },
+        }], {
+          total: {
+            label: 'Total',
+            amount: {
+              currency: 'USD',
+              value: '5.00',
+            },
+          },
+        })
+      .canMakePayment()
+      .then(function(result) {
+        print(result);
+      })
+      .catch(function(error) {
+        print(error);
+      });
+  } catch (error) {
+    print(error);
+  }
+}
+
+/**
+ * Merchant checks for ability to pay using "mastercard".
+ */
+function checkMasterCard() { // eslint-disable-line no-unused-vars
+  try {
+    new PaymentRequest(
+        [{
+          supportedMethods: ['mastercard'],
+        }], {
+          total: {
+            label: 'Total',
+            amount: {
+              currency: 'USD',
+              value: '5.00',
+            },
+          },
+        })
+      .canMakePayment()
+      .then(function(result) {
+        print(result);
+      })
+      .catch(function(error) {
+        print(error);
+      });
+  } catch (error) {
+    print(error);
+  }
+}
+
+/**
+ * Merchant checks for ability to pay using "visa".
+ */
+function checkVisa() { // eslint-disable-line no-unused-vars
+  try {
+    new PaymentRequest(
+        [{
+          supportedMethods: ['visa'],
+        }], {
+          total: {
+            label: 'Total',
+            amount: {
+              currency: 'USD',
+              value: '5.00',
+            },
+          },
+        })
+      .canMakePayment()
+      .then(function(result) {
+        print(result);
+      })
+      .catch(function(error) {
+        print(error);
+      });
+  } catch (error) {
+    print(error);
+  }
+}
+
+/**
+ * Merchant requests payment via either "mastercard" or "basic-card" with "visa"
+ * as the supported network.
+ */
+function buy() { // eslint-disable-line no-unused-vars
+  try {
+    new PaymentRequest(
+        [{
+          supportedMethods: ['mastercard'],
+        }, {
+          supportedMethods: ['basic-card'],
+          data: {
+            supportedNetworks: ['visa'],
+          },
+        }], {
+          total: {
+            label: 'Total',
+            amount: {
+              currency: 'USD',
+              value: '5.00',
+            },
+          },
+        })
+      .show()
+      .then(function(response) {
+        response.complete('success').then(function() {
+          print(JSON.stringify(response, undefined, 2));
+        }).catch(function(error) {
+          print(error);
+        });
+      })
+      .catch(function(error) {
+        print(error);
+      });
+  } catch (error) {
+    print(error);
+  }
+}
+
+/**
+ * Merchant requests payment via "basic-card" with "debit" as the supported card
+ * type.
+ */
+function buyBasicDebit() { // eslint-disable-line no-unused-vars
+  try {
+    new PaymentRequest(
+        [{
+          supportedMethods: ['basic-card'],
+          data: {
+            supportedTypes: ['debit'],
+          },
+        }], {
+          total: {
+            label: 'Total',
+            amount: {
+              currency: 'USD',
+              value: '5.00',
+            },
+          },
+        })
+      .show()
+      .then(function(response) {
+        response.complete('success').then(function() {
+          print(JSON.stringify(response, undefined, 2));
+        }).catch(function(error) {
+          print(error);
+        });
+      })
+      .catch(function(error) {
+        print(error);
+      });
+  } catch (error) {
+    print(error);
+  }
+}
+
+/**
+ * Merchant requests payment via "basic-card" payment method with "mastercard"
+ * as the only supported network.
+ */
+function buyBasicMasterCard() { // eslint-disable-line no-unused-vars
+  try {
+    new PaymentRequest(
+        [{
+          supportedMethods: ['basic-card'],
+          data: {
+            supportedNetworks: ['mastercard'],
+          },
+        }], {
+          total: {
+            label: 'Total',
+            amount: {
+              currency: 'USD',
+              value: '5.00',
+            },
+          },
+        })
+      .show()
+      .then(function(response) {
+        response.complete('success').then(function() {
+          print(JSON.stringify(response, undefined, 2));
+        }).catch(function(error) {
+          print(error);
+        });
+      })
+      .catch(function(error) {
+        print(error);
+      });
+  } catch (error) {
+    print(error);
+  }
+}
diff --git a/chrome/test/data/android/payments/payment_request_basic_card_test.html b/chrome/test/data/android/payments/payment_request_basic_card_test.html
new file mode 100644
index 0000000..c65ec745
--- /dev/null
+++ b/chrome/test/data/android/payments/payment_request_basic_card_test.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<!--
+Copyright 2016 The Chromium Authors. All rights reserved.
+Use of this source code is governed by a BSD-style license that can be
+found in the LICENSE file.
+-->
+<html>
+<head>
+<title>Basic Card Test</title>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
+</head>
+<body>
+<button onclick="checkBasicDebit()" id="checkBasicDebit">Check Basic Debit</button>
+<button onclick="checkBasicMasterCard()" id="checkBasicMasterCard">Check Basic MasterCard</button>
+<button onclick="checkBasicVisa()" id="checkBasicVisa">Check Basic Visa</button>
+<button onclick="checkMasterCard()" id="checkMasterCard">Check MasterCard</button>
+<button onclick="checkVisa()" id="checkVisa">Check Visa</button>
+<button onclick="buy()" id="buy">Basic Card Test</button>
+<button onclick="buyBasicDebit()" id="buyBasicDebit">Buy With Basic Debit Card</button>
+<button onclick="buyBasicMasterCard()" id="buyBasicMasterCard">Buy With Basic MasterCardTest</button>
+<pre id="result"></pre>
+<script src="util.js"></script>
+<script src="basic_card.js"></script>
+</body>
+</html>
diff --git a/chrome/test/data/predictors/html_subresources.html b/chrome/test/data/predictors/html_subresources.html
index f3a24ca..23c31ea3 100644
--- a/chrome/test/data/predictors/html_subresources.html
+++ b/chrome/test/data/predictors/html_subresources.html
@@ -12,8 +12,8 @@
         font-family: "Whatever", Verdana;
       }
     </style>
+    <script src="/handled-by-test/script.js"></script>
   </head>
-  <script src="/handled-by-test/script.js"></script>
   <body>
     <img src="/handled-by-test/image.png">
     <p class="customfont">Hello world!</p>
diff --git a/chrome/test/data/predictors/javascript_redirect.html b/chrome/test/data/predictors/javascript_redirect.html
new file mode 100644
index 0000000..47ffece7
--- /dev/null
+++ b/chrome/test/data/predictors/javascript_redirect.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>Changes document location</title>
+    <script src="javascript_redirect.js"></script>
+  </head>
+  <body>
+  </body>
+</html>
diff --git a/chrome/test/data/predictors/javascript_redirect.js b/chrome/test/data/predictors/javascript_redirect.js
new file mode 100644
index 0000000..02f2e53
--- /dev/null
+++ b/chrome/test/data/predictors/javascript_redirect.js
@@ -0,0 +1,17 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function getUrlParameters() {
+  var result = {};
+  var parts = window.location.search.substring(1).split('&');
+  for (var i = 0; i < parts.length; i++) {
+    var pair = parts[i].split('=');
+    result[pair[0]] = decodeURIComponent(pair[1]);
+  }
+  return result;
+}
+
+var params = getUrlParameters();
+var redirectUrl = params["url"];
+location.href = redirectUrl;
diff --git a/components/payments/payment_request.mojom b/components/payments/payment_request.mojom
index 863d439..d702e00 100644
--- a/components/payments/payment_request.mojom
+++ b/components/payments/payment_request.mojom
@@ -106,6 +106,45 @@
   bool selected;
 };
 
+enum AndroidPayEnvironment {
+  PRODUCTION,
+  TEST
+};
+
+enum AndroidPayCardNetwork {
+  AMEX,
+  DISCOVER,
+  MASTERCARD,
+  VISA
+};
+
+enum AndroidPayTokenization {
+  UNSPECIFIED,
+  GATEWAY_TOKEN,
+  NETWORK_TOKEN
+};
+
+struct AndroidPayTokenizationParameter {
+  string? key;
+  string? value;
+};
+
+enum BasicCardNetwork {
+  AMEX,
+  DINERS,
+  DISCOVER,
+  JCB,
+  MASTERCARD,
+  UNIONPAY,
+  VISA
+};
+
+enum BasicCardType {
+  CREDIT,
+  DEBIT,
+  PREPAID
+};
+
 struct PaymentMethodData {
   array<string> supported_methods;
 
@@ -130,6 +169,10 @@
   array<AndroidPayTokenizationParameter> parameters;
   // Value of 0 means the merchant did not specify or it was an invalid value.
   int32 min_google_play_services_version;
+
+  // Basic card specific method data is parsed in the renderer.
+  array<BasicCardNetwork> supported_networks;
+  array<BasicCardType> supported_types;
 };
 
 struct PaymentDetailsModifier {
@@ -160,29 +203,6 @@
   PaymentShippingType shipping_type;
 };
 
-enum AndroidPayEnvironment {
-  PRODUCTION,
-  TEST
-};
-
-enum AndroidPayCardNetwork {
-  AMEX,
-  DISCOVER,
-  MASTERCARD,
-  VISA
-};
-
-enum AndroidPayTokenization {
-  UNSPECIFIED,
-  GATEWAY_TOKEN,
-  NETWORK_TOKEN
-};
-
-struct AndroidPayTokenizationParameter {
-  string? key;
-  string? value;
-};
-
 enum PaymentComplete {
   SUCCESS,
   FAIL,
diff --git a/components/reading_list/ios/reading_list_model.h b/components/reading_list/ios/reading_list_model.h
index f6850e0..73968eea 100644
--- a/components/reading_list/ios/reading_list_model.h
+++ b/components/reading_list/ios/reading_list_model.h
@@ -69,11 +69,17 @@
   // Mark all unseen entries as unread.
   virtual void MarkAllSeen() = 0;
 
-  // Returns true if there are entries in the model that were not seen by the
-  // user yet. Reset to true when new unread entries are added. Reset to false
-  // when ResetUnseenEntries is called.
-  virtual bool HasUnseenEntries() const = 0;
-  virtual void ResetUnseenEntries() = 0;
+  // Returns the flag about unseen entries on the device.
+  // This flag is raised if some unseen items are added on this device.
+  // The flag is reset if |ResetLocalUnseenFlag| is called or if all unseen
+  // entries are removed.
+  // This is a local flag and it can have different values on different devices,
+  // even if they are synced.
+  // (unseen_size() == 0 => GetLocalUnseenFlag() == false)
+  virtual bool GetLocalUnseenFlag() const = 0;
+
+  // Set the unseen flag to false.
+  virtual void ResetLocalUnseenFlag() = 0;
 
   // Returns a specific entry. Returns null if the entry does not exist.
   virtual const ReadingListEntry* GetEntryByURL(const GURL& gurl) const = 0;
diff --git a/components/reading_list/ios/reading_list_model_impl.cc b/components/reading_list/ios/reading_list_model_impl.cc
index fa3a9bc..acb08106 100644
--- a/components/reading_list/ios/reading_list_model_impl.cc
+++ b/components/reading_list/ios/reading_list_model_impl.cc
@@ -87,14 +87,26 @@
   return unseen_entry_count_;
 }
 
-bool ReadingListModelImpl::HasUnseenEntries() const {
+void ReadingListModelImpl::SetUnseenFlag() {
+  if (!has_unseen_) {
+    has_unseen_ = true;
+    if (!IsPerformingBatchUpdates()) {
+      SetPersistentHasUnseen(true);
+    }
+  }
+}
+
+bool ReadingListModelImpl::GetLocalUnseenFlag() const {
   DCHECK(CalledOnValidThread());
   if (!loaded())
     return false;
-  return has_unseen_;
+  // If there are currently no unseen entries, return false even if has_unseen_
+  // is true.
+  // This is possible if the last unseen entry has be removed via sync.
+  return has_unseen_ && unseen_entry_count_;
 }
 
-void ReadingListModelImpl::ResetUnseenEntries() {
+void ReadingListModelImpl::ResetLocalUnseenFlag() {
   DCHECK(CalledOnValidThread());
   DCHECK(loaded());
   has_unseen_ = false;
@@ -224,8 +236,8 @@
   for (auto& observer : observers_)
     observer.ReadingListWillAddEntry(this, *entry);
   UpdateEntryStateCountersOnEntryInsertion(*entry);
-  if (!entry->IsRead()) {
-    SetPersistentHasUnseen(true);
+  if (!entry->HasBeenSeen()) {
+    SetUnseenFlag();
   }
   GURL url = entry->URL();
   entries_->insert(std::make_pair(url, std::move(*entry)));
@@ -246,11 +258,15 @@
   for (auto& observer : observers_)
     observer.ReadingListWillMoveEntry(this, url);
 
+  bool was_seen = existing_entry->HasBeenSeen();
   UpdateEntryStateCountersOnEntryRemoval(*existing_entry);
   existing_entry->MergeWithEntry(*entry);
   existing_entry = GetMutableEntryFromURL(url);
   UpdateEntryStateCountersOnEntryInsertion(*existing_entry);
-
+  if (was_seen && !existing_entry->HasBeenSeen()) {
+    // Only set the flag if a new unseen entry is added.
+    SetUnseenFlag();
+  }
   for (auto& observer : observers_) {
     observer.ReadingListDidMoveEntry(this, url);
     observer.ReadingListDidApplyChanges(this);
@@ -282,6 +298,7 @@
     storage_layer_->RemoveEntry(*entry);
   }
   UpdateEntryStateCountersOnEntryRemoval(*entry);
+
   entries_->erase(url);
   for (auto& observer : observers_)
     observer.ReadingListDidApplyChanges(this);
@@ -301,9 +318,8 @@
   ReadingListEntry entry(url, trimmedTitle);
   for (auto& observer : observers_)
     observer.ReadingListWillAddEntry(this, entry);
-  has_unseen_ = true;
-  SetPersistentHasUnseen(true);
   UpdateEntryStateCountersOnEntryInsertion(entry);
+  SetUnseenFlag();
   entries_->insert(std::make_pair(url, std::move(entry)));
 
   if (storage_layer_) {
@@ -336,6 +352,7 @@
   entry.SetRead(read);
   entry.MarkEntryUpdated();
   UpdateEntryStateCountersOnEntryInsertion(entry);
+
   if (storage_layer_) {
     storage_layer_->SaveEntry(entry);
   }
diff --git a/components/reading_list/ios/reading_list_model_impl.h b/components/reading_list/ios/reading_list_model_impl.h
index 352dc57..8d31540 100644
--- a/components/reading_list/ios/reading_list_model_impl.h
+++ b/components/reading_list/ios/reading_list_model_impl.h
@@ -49,8 +49,8 @@
   size_t unseen_size() const override;
 
   void MarkAllSeen() override;
-  bool HasUnseenEntries() const override;
-  void ResetUnseenEntries() override;
+  bool GetLocalUnseenFlag() const override;
+  void ResetLocalUnseenFlag() override;
 
   const std::vector<GURL> Keys() const override;
 
@@ -124,6 +124,9 @@
   void UpdateEntryStateCountersOnEntryRemoval(const ReadingListEntry& entry);
   void UpdateEntryStateCountersOnEntryInsertion(const ReadingListEntry& entry);
 
+  // Set the unseen flag to true.
+  void SetUnseenFlag();
+
   std::unique_ptr<ReadingListModelStorage> storage_layer_;
   PrefService* pref_service_;
   bool has_unseen_;
diff --git a/components/reading_list/ios/reading_list_model_unittest.mm b/components/reading_list/ios/reading_list_model_unittest.mm
index bf7c1b10..768b346 100644
--- a/components/reading_list/ios/reading_list_model_unittest.mm
+++ b/components/reading_list/ios/reading_list_model_unittest.mm
@@ -341,7 +341,7 @@
   AssertStorageCount(1, 0);
   EXPECT_EQ(1ul, UnreadSize());
   EXPECT_EQ(0ul, ReadSize());
-  EXPECT_TRUE(model_->HasUnseenEntries());
+  EXPECT_TRUE(model_->GetLocalUnseenFlag());
 
   const ReadingListEntry* other_entry =
       model_->GetEntryByURL(GURL("http://example.com"));
@@ -502,10 +502,12 @@
 TEST_F(ReadingListModelTest, UnreadEntry) {
   // Setup.
   model_->AddEntry(GURL("http://example.com"), "sample");
+  EXPECT_TRUE(model_->GetLocalUnseenFlag());
   model_->SetReadStatus(GURL("http://example.com"), true);
   ClearCounts();
   EXPECT_EQ(0ul, UnreadSize());
   EXPECT_EQ(1ul, ReadSize());
+  EXPECT_FALSE(model_->GetLocalUnseenFlag());
 
   // Action.
   model_->SetReadStatus(GURL("http://example.com"), false);
@@ -514,7 +516,7 @@
   AssertObserverCount(0, 0, 0, 0, 0, 1, 0, 0, 1);
   EXPECT_EQ(1ul, UnreadSize());
   EXPECT_EQ(0ul, ReadSize());
-  EXPECT_TRUE(model_->HasUnseenEntries());
+  EXPECT_FALSE(model_->GetLocalUnseenFlag());
 
   const ReadingListEntry* other_entry =
       model_->GetEntryByURL(GURL("http://example.com"));
diff --git a/components/search_engines/default_search_manager.cc b/components/search_engines/default_search_manager.cc
index a7e2919c..a49e931 100644
--- a/components/search_engines/default_search_manager.cc
+++ b/components/search_engines/default_search_manager.cc
@@ -200,10 +200,9 @@
   if (!prefs_default_search_ || !prefs_default_search_->prepopulate_id)
     return;
 
-  size_t default_search_index;
   std::vector<std::unique_ptr<TemplateURLData>> prepopulated_urls =
       TemplateURLPrepopulateData::GetPrepopulatedEngines(pref_service_,
-                                                         &default_search_index);
+                                                         nullptr);
 
   for (auto& engine : prepopulated_urls) {
     if (engine->prepopulate_id != prefs_default_search_->prepopulate_id)
diff --git a/components/search_engines/template_url_prepopulate_data.cc b/components/search_engines/template_url_prepopulate_data.cc
index 38301ce6a..a7c7e1e 100644
--- a/components/search_engines/template_url_prepopulate_data.cc
+++ b/components/search_engines/template_url_prepopulate_data.cc
@@ -1032,7 +1032,8 @@
     size_t* default_search_provider_index) {
   // If there is a set of search engines in the preferences file, it overrides
   // the built-in set.
-  *default_search_provider_index = 0;
+  if (default_search_provider_index)
+    *default_search_provider_index = 0;
   std::vector<std::unique_ptr<TemplateURLData>> t_urls =
       GetPrepopulatedTemplateURLData(prefs);
   if (!t_urls.empty())
diff --git a/components/search_engines/template_url_prepopulate_data.h b/components/search_engines/template_url_prepopulate_data.h
index 1b39778..8f25362 100644
--- a/components/search_engines/template_url_prepopulate_data.h
+++ b/components/search_engines/template_url_prepopulate_data.h
@@ -36,8 +36,8 @@
 int GetDataVersion(PrefService* prefs);
 
 // Returns the prepopulated URLs for the current country.
-// |default_search_provider_index| is set to the index of the default search
-// provider within the returned vector.
+// If |default_search_provider_index| is non-null, it is set to the index of the
+// default search provider within the returned vector.
 std::vector<std::unique_ptr<TemplateURLData>> GetPrepopulatedEngines(
     PrefService* prefs,
     size_t* default_search_provider_index);
diff --git a/components/search_engines/template_url_prepopulate_data_unittest.cc b/components/search_engines/template_url_prepopulate_data_unittest.cc
index 6984825..de61220 100644
--- a/components/search_engines/template_url_prepopulate_data_unittest.cc
+++ b/components/search_engines/template_url_prepopulate_data_unittest.cc
@@ -105,10 +105,8 @@
 
   for (size_t i = 0; i < arraysize(kCountryIds); ++i) {
     prefs_.SetInteger(prefs::kCountryIDAtInstall, kCountryIds[i]);
-    size_t default_index;
     std::vector<std::unique_ptr<TemplateURLData>> urls =
-        TemplateURLPrepopulateData::GetPrepopulatedEngines(&prefs_,
-                                                           &default_index);
+        TemplateURLPrepopulateData::GetPrepopulatedEngines(&prefs_, nullptr);
     std::set<int> unique_ids;
     for (size_t turl_i = 0; turl_i < urls.size(); ++turl_i) {
       ASSERT_TRUE(unique_ids.find(urls[turl_i]->prepopulate_id) ==
diff --git a/components/search_engines/template_url_service.cc b/components/search_engines/template_url_service.cc
index 123a6d0..29687f2 100644
--- a/components/search_engines/template_url_service.cc
+++ b/components/search_engines/template_url_service.cc
@@ -678,10 +678,8 @@
     default_search_provider_ = nullptr;
   }
 
-  size_t default_search_provider_index = 0;
   std::vector<std::unique_ptr<TemplateURLData>> prepopulated_urls =
-      TemplateURLPrepopulateData::GetPrepopulatedEngines(
-          prefs_, &default_search_provider_index);
+      TemplateURLPrepopulateData::GetPrepopulatedEngines(prefs_, nullptr);
   DCHECK(!prepopulated_urls.empty());
   ActionsFromPrepopulateData actions(CreateActionsFromCurrentPrepopulateData(
       &prepopulated_urls, template_urls_, default_search_provider_));
@@ -1752,10 +1750,8 @@
   if (template_url->prepopulate_id() == 0)
     return;
 
-  size_t default_search_index;
   std::vector<std::unique_ptr<TemplateURLData>> prepopulated_urls =
-      TemplateURLPrepopulateData::GetPrepopulatedEngines(prefs,
-                                                         &default_search_index);
+      TemplateURLPrepopulateData::GetPrepopulatedEngines(prefs, nullptr);
 
   for (const auto& url : prepopulated_urls) {
     if (url->prepopulate_id == prepopulate_id) {
diff --git a/components/security_interstitials/content/security_interstitial_page.cc b/components/security_interstitials/content/security_interstitial_page.cc
index 90c54a9e..6ff9b3a 100644
--- a/components/security_interstitials/content/security_interstitial_page.cc
+++ b/components/security_interstitials/content/security_interstitial_page.cc
@@ -33,6 +33,11 @@
       interstitial_page_(NULL),
       create_view_(true),
       controller_(std::move(controller)) {
+  // Determine if any prefs need to be updated prior to showing the security
+  // interstitial.
+  safe_browsing::UpdatePrefsBeforeSecurityInterstitial(
+      controller_->GetPrefService());
+
   // Creating interstitial_page_ without showing it leaks memory, so don't
   // create it here.
 }
@@ -63,11 +68,6 @@
   if (!create_view_)
     interstitial_page_->DontCreateViewForTesting();
 
-  // Determine if any prefs need to be updated prior to showing the security
-  // interstitial.
-  safe_browsing::UpdatePrefsBeforeSecurityInterstitial(
-      controller_->GetPrefService());
-
   interstitial_page_->Show();
 
   controller_->set_interstitial_page(interstitial_page_);
diff --git a/content/OWNERS b/content/OWNERS
index b7b2e3f6f..96de475 100644
--- a/content/OWNERS
+++ b/content/OWNERS
@@ -1,3 +1,4 @@
+alexmos@chromium.org
 avi@chromium.org
 clamy@chromium.org
 creis@chromium.org
diff --git a/content/browser/cache_storage/cache_storage.cc b/content/browser/cache_storage/cache_storage.cc
index d32fc3d9..b565cc0 100644
--- a/content/browser/cache_storage/cache_storage.cc
+++ b/content/browser/cache_storage/cache_storage.cc
@@ -59,7 +59,7 @@
 }  // namespace
 
 const char CacheStorage::kIndexFileName[] = "index.txt";
-const int64_t CacheStorage::kSizeUnknown;
+constexpr int64_t CacheStorage::kSizeUnknown;
 
 struct CacheStorage::CacheMatchResponse {
   CacheMatchResponse() = default;
diff --git a/content/browser/download/download_create_info.cc b/content/browser/download/download_create_info.cc
index c98fd2b..244c7d2 100644
--- a/content/browser/download/download_create_info.cc
+++ b/content/browser/download/download_create_info.cc
@@ -20,7 +20,6 @@
       start_time(start_time),
       total_bytes(0),
       has_user_gesture(false),
-      transition_type(ui::PAGE_TRANSITION_LINK),
       result(DOWNLOAD_INTERRUPT_REASON_NONE),
       save_info(std::move(save_info)),
       request_net_log(net_log) {}
diff --git a/content/browser/download/download_create_info.h b/content/browser/download/download_create_info.h
index 0c715345..c0c7f17 100644
--- a/content/browser/download/download_create_info.h
+++ b/content/browser/download/download_create_info.h
@@ -12,6 +12,7 @@
 
 #include "base/files/file_path.h"
 #include "base/macros.h"
+#include "base/optional.h"
 #include "base/time/time.h"
 #include "content/browser/download/download_file.h"
 #include "content/browser/download/download_request_handle.h"
@@ -64,7 +65,7 @@
   // True if the download was initiated by user action.
   bool has_user_gesture;
 
-  ui::PageTransition transition_type;
+  base::Optional<ui::PageTransition> transition_type;
 
   // The remote IP address where the download was fetched from.  Copied from
   // UrlRequest::GetSocketAddress().
diff --git a/content/browser/download/download_item_impl.cc b/content/browser/download/download_item_impl.cc
index 9f9eae5..c696d1b 100644
--- a/content/browser/download/download_item_impl.cc
+++ b/content/browser/download/download_item_impl.cc
@@ -196,7 +196,8 @@
       tab_referrer_url_(info.tab_referrer_url),
       suggested_filename_(base::UTF16ToUTF8(info.save_info->suggested_name)),
       forced_file_path_(info.save_info->file_path),
-      transition_type_(info.transition_type),
+      transition_type_(info.transition_type ? info.transition_type.value()
+                                            : ui::PAGE_TRANSITION_LINK),
       has_user_gesture_(info.has_user_gesture),
       content_disposition_(info.content_disposition),
       mime_type_(info.mime_type),
diff --git a/content/browser/download/download_request_core.cc b/content/browser/download/download_request_core.cc
index b5c504ba..0fec3f3 100644
--- a/content/browser/download/download_request_core.cc
+++ b/content/browser/download/download_request_core.cc
@@ -334,6 +334,7 @@
 
   RecordDownloadMimeType(create_info->mime_type);
   RecordDownloadContentDisposition(create_info->content_disposition);
+  RecordDownloadSourcePageTransitionType(create_info->transition_type);
 
   delegate_->OnStart(std::move(create_info), std::move(stream_reader),
                      base::ResetAndReturn(&on_started_callback_));
diff --git a/content/browser/download/download_stats.cc b/content/browser/download/download_stats.cc
index 3c871dbd..87fbe19 100644
--- a/content/browser/download/download_stats.cc
+++ b/content/browser/download/download_stats.cc
@@ -790,4 +790,15 @@
                             DOWNLOAD_CONNECTION_SECURITY_MAX);
 }
 
+void RecordDownloadSourcePageTransitionType(
+    const base::Optional<ui::PageTransition>& page_transition) {
+  if (!page_transition)
+    return;
+
+  UMA_HISTOGRAM_ENUMERATION(
+      "Download.PageTransition",
+      ui::PageTransitionStripQualifier(page_transition.value()),
+      ui::PAGE_TRANSITION_LAST_CORE + 1);
+}
+
 }  // namespace content
diff --git a/content/browser/download/download_stats.h b/content/browser/download/download_stats.h
index 5479bca..fcc8ff9 100644
--- a/content/browser/download/download_stats.h
+++ b/content/browser/download/download_stats.h
@@ -13,9 +13,11 @@
 #include <string>
 #include <vector>
 
+#include "base/optional.h"
 #include "content/common/content_export.h"
 #include "content/public/browser/download_danger_type.h"
 #include "content/public/browser/download_interrupt_reasons.h"
+#include "ui/base/page_transition_types.h"
 #include "url/gurl.h"
 
 namespace base {
@@ -241,6 +243,9 @@
 void RecordDownloadConnectionSecurity(const GURL& download_url,
                                       const std::vector<GURL>& url_chain);
 
+void RecordDownloadSourcePageTransitionType(
+    const base::Optional<ui::PageTransition>& transition);
+
 }  // namespace content
 
 #endif  // CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_STATS_H_
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
index c42b652..b95ef8c 100644
--- a/content/browser/frame_host/render_frame_host_impl.cc
+++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -125,7 +125,9 @@
 #include "content/browser/frame_host/popup_menu_helper_mac.h"
 #endif
 
+#if defined(ENABLE_WEBVR)
 #include "device/vr/vr_service_impl.h"  // nogncheck
+#endif
 
 using base::TimeDelta;
 
@@ -237,11 +239,6 @@
 };
 #endif  // BUILDFLAG(ENABLE_MEDIA_REMOTING)
 
-template <typename Interface>
-void IgnoreInterfaceRequest(mojo::InterfaceRequest<Interface> request) {
-  // Intentionally ignore the interface request.
-}
-
 }  // namespace
 
 // static
@@ -2311,11 +2308,7 @@
 #if defined(ENABLE_WEBVR)
   GetInterfaceRegistry()->AddInterface<device::mojom::VRService>(
       base::Bind(&device::VRServiceImpl::Create));
-#else
-  GetInterfaceRegistry()->AddInterface<device::mojom::VRService>(
-      base::Bind(&IgnoreInterfaceRequest<device::mojom::VRService>));
 #endif
-
   if (base::FeatureList::IsEnabled(features::kGenericSensor)) {
     GetInterfaceRegistry()->AddInterface(
         base::Bind(&device::SensorProviderImpl::Create,
diff --git a/content/browser/renderer_host/media/audio_input_renderer_host.cc b/content/browser/renderer_host/media/audio_input_renderer_host.cc
index 661924a..444761c 100644
--- a/content/browser/renderer_host/media/audio_input_renderer_host.cc
+++ b/content/browser/renderer_host/media/audio_input_renderer_host.cc
@@ -148,14 +148,6 @@
                  base::RetainedRef(controller)));
 }
 
-void AudioInputRendererHost::OnRecording(
-    media::AudioInputController* controller) {
-  BrowserThread::PostTask(
-      BrowserThread::IO, FROM_HERE,
-      base::Bind(&AudioInputRendererHost::DoSendRecordingMessage, this,
-                 base::RetainedRef(controller)));
-}
-
 void AudioInputRendererHost::OnError(media::AudioInputController* controller,
     media::AudioInputController::ErrorCode error_code) {
   BrowserThread::PostTask(
@@ -222,17 +214,6 @@
       entry->shared_memory_segment_count));
 }
 
-void AudioInputRendererHost::DoSendRecordingMessage(
-    media::AudioInputController* controller) {
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  // TODO(henrika): See crbug.com/115262 for details on why this method
-  // should be implemented.
-  AudioEntry* entry = LookupByController(controller);
-  DCHECK(entry) << "AudioInputController is invalid.";
-  LogMessage(
-      entry->stream_id, "DoSendRecordingMessage: stream is now started", true);
-}
-
 void AudioInputRendererHost::DoHandleError(
     media::AudioInputController* controller,
     media::AudioInputController::ErrorCode error_code) {
@@ -499,8 +480,7 @@
       base::StringPrintf("SendErrorMessage(error_code=%d)", error_code);
   LogMessage(stream_id, err_msg, true);
 
-  Send(new AudioInputMsg_NotifyStreamStateChanged(
-      stream_id, media::AUDIO_INPUT_IPC_DELEGATE_STATE_ERROR));
+  Send(new AudioInputMsg_NotifyStreamError(stream_id));
 }
 
 void AudioInputRendererHost::DeleteEntries() {
diff --git a/content/browser/renderer_host/media/audio_input_renderer_host.h b/content/browser/renderer_host/media/audio_input_renderer_host.h
index a6fa5ae..e4bf199cc 100644
--- a/content/browser/renderer_host/media/audio_input_renderer_host.h
+++ b/content/browser/renderer_host/media/audio_input_renderer_host.h
@@ -106,7 +106,6 @@
 
   // AudioInputController::EventHandler implementation.
   void OnCreated(media::AudioInputController* controller) override;
-  void OnRecording(media::AudioInputController* controller) override;
   void OnError(media::AudioInputController* controller,
                media::AudioInputController::ErrorCode error_code) override;
   void OnData(media::AudioInputController* controller,
diff --git a/content/browser/renderer_host/media/audio_input_renderer_host_unittest.cc b/content/browser/renderer_host/media/audio_input_renderer_host_unittest.cc
index 46863921..55a3af35 100644
--- a/content/browser/renderer_host/media/audio_input_renderer_host_unittest.cc
+++ b/content/browser/renderer_host/media/audio_input_renderer_host_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "content/browser/renderer_host/media/audio_input_renderer_host.h"
 
+#include <utility>
 #include <vector>
 
 #include "base/bind.h"
@@ -78,10 +79,7 @@
                     base::SyncSocket::TransitDescriptor /*socket_desriptor*/,
                     uint32_t /*length*/,
                     uint32_t /*total_segments*/));
-  MOCK_METHOD2(NotifyStreamVolume, void(int /*stream_id*/, double /*volume*/));
-  MOCK_METHOD2(NotifyStreamStateChanged,
-               void(int /*stream_id*/,
-                    media::AudioInputIPCDelegateState /*state*/));
+  MOCK_METHOD1(NotifyStreamError, void(int /*stream_id*/));
   MOCK_METHOD0(WasShutDown, void());
 };
 
@@ -119,10 +117,8 @@
     IPC_BEGIN_MESSAGE_MAP(AudioInputRendererHostWithInterception, *message)
       IPC_MESSAGE_HANDLER(AudioInputMsg_NotifyStreamCreated,
                           NotifyRendererStreamCreated)
-      IPC_MESSAGE_HANDLER(AudioInputMsg_NotifyStreamVolume,
-                          NotifyRendererStreamVolume)
-      IPC_MESSAGE_HANDLER(AudioInputMsg_NotifyStreamStateChanged,
-                          NotifyRendererStreamStateChanged)
+      IPC_MESSAGE_HANDLER(AudioInputMsg_NotifyStreamError,
+                          NotifyRendererStreamError)
       IPC_MESSAGE_UNHANDLED(handled = false)
     IPC_END_MESSAGE_MAP()
 
@@ -151,14 +147,8 @@
     memory.Close();
   }
 
-  void NotifyRendererStreamVolume(int stream_id, double volume) {
-    renderer_->NotifyStreamVolume(stream_id, volume);
-  }
-
-  void NotifyRendererStreamStateChanged(
-      int stream_id,
-      media::AudioInputIPCDelegateState state) {
-    renderer_->NotifyStreamStateChanged(stream_id, state);
+  void NotifyRendererStreamError(int stream_id) {
+    renderer_->NotifyStreamError(stream_id);
   }
 
   MockRenderer* renderer_;
@@ -345,9 +335,7 @@
 // If authorization hasn't been granted, only reply with and error and do
 // nothing else.
 TEST_F(AudioInputRendererHostTest, CreateWithoutAuthorization_Error) {
-  EXPECT_CALL(renderer_,
-              NotifyStreamStateChanged(
-                  kStreamId, media::AUDIO_INPUT_IPC_DELEGATE_STATE_ERROR));
+  EXPECT_CALL(renderer_, NotifyStreamError(kStreamId));
 
   int session_id = 0;
   airh_->OnMessageReceived(AudioInputHostMsg_CreateStream(
@@ -467,9 +455,7 @@
 
   EXPECT_CALL(renderer_,
               NotifyStreamCreated(kStreamId, _, _, _, kSharedMemoryCount));
-  EXPECT_CALL(renderer_,
-              NotifyStreamStateChanged(
-                  kStreamId, media::AUDIO_INPUT_IPC_DELEGATE_STATE_ERROR));
+  EXPECT_CALL(renderer_, NotifyStreamError(kStreamId));
   EXPECT_CALL(controller_factory_, ControllerCreated());
 
   airh_->OnMessageReceived(AudioInputHostMsg_CreateStream(
@@ -534,9 +520,7 @@
 
   base::RunLoop().RunUntilIdle();
   EXPECT_CALL(*controller_factory_.controller(0), Close(_));
-  EXPECT_CALL(renderer_,
-              NotifyStreamStateChanged(
-                  kStreamId, media::AUDIO_INPUT_IPC_DELEGATE_STATE_ERROR));
+  EXPECT_CALL(renderer_, NotifyStreamError(kStreamId));
 
   controller_factory_.controller(0)->handler()->OnError(
       controller_factory_.controller(0), AudioInputController::UNKNOWN_ERROR);
diff --git a/content/browser/speech/speech_recognizer_impl.h b/content/browser/speech/speech_recognizer_impl.h
index a9171c3..e0a632e9 100644
--- a/content/browser/speech/speech_recognizer_impl.h
+++ b/content/browser/speech/speech_recognizer_impl.h
@@ -132,7 +132,6 @@
 
   // AudioInputController::EventHandler methods.
   void OnCreated(media::AudioInputController* controller) override {}
-  void OnRecording(media::AudioInputController* controller) override {}
   void OnError(media::AudioInputController* controller,
                media::AudioInputController::ErrorCode error_code) override;
   void OnData(media::AudioInputController* controller,
diff --git a/content/common/media/audio_messages.h b/content/common/media/audio_messages.h
index 5a3f6316..aed2973 100644
--- a/content/common/media/audio_messages.h
+++ b/content/common/media/audio_messages.h
@@ -23,9 +23,6 @@
 #define IPC_MESSAGE_EXPORT CONTENT_EXPORT
 #define IPC_MESSAGE_START AudioMsgStart
 
-IPC_ENUM_TRAITS_MAX_VALUE(media::AudioInputIPCDelegateState,
-                          media::AUDIO_INPUT_IPC_DELEGATE_STATE_LAST)
-
 IPC_ENUM_TRAITS_MAX_VALUE(media::OutputDeviceStatus,
                           media::OUTPUT_DEVICE_STATUS_MAX)
 
@@ -74,13 +71,7 @@
 IPC_MESSAGE_CONTROL1(AudioMsg_NotifyStreamError, int /* stream id */)
 
 // Notification message sent from browser to renderer for state update.
-IPC_MESSAGE_CONTROL2(AudioInputMsg_NotifyStreamStateChanged,
-                     int /* stream id */,
-                     media::AudioInputIPCDelegateState /* new state */)
-
-IPC_MESSAGE_CONTROL2(AudioInputMsg_NotifyStreamVolume,
-                     int /* stream id */,
-                     double /* volume */)
+IPC_MESSAGE_CONTROL1(AudioInputMsg_NotifyStreamError, int /* stream id */)
 
 // Messages sent from the renderer to the browser.
 
diff --git a/content/public/app/mojo/content_browser_manifest.json b/content/public/app/mojo/content_browser_manifest.json
index ad2bbda..d9d9203 100644
--- a/content/public/app/mojo/content_browser_manifest.json
+++ b/content/public/app/mojo/content_browser_manifest.json
@@ -77,6 +77,7 @@
           "blink::mojom::PermissionService",
           "blink::mojom::PresentationService",
           "blink::mojom::SensitiveInputVisibilityService",
+          "blink::mojom::TextDetection",
           "blink::mojom::WebBluetoothService",
           "blink::mojom::WebSocket",
           // TODO(beng): figure out how to overlay test interfaces like this.
diff --git a/content/renderer/media/audio_input_message_filter.cc b/content/renderer/media/audio_input_message_filter.cc
index 1659af3c8..46b4e4c 100644
--- a/content/renderer/media/audio_input_message_filter.cc
+++ b/content/renderer/media/audio_input_message_filter.cc
@@ -4,6 +4,8 @@
 
 #include "content/renderer/media/audio_input_message_filter.h"
 
+#include <string>
+
 #include "base/bind.h"
 #include "base/single_thread_task_runner.h"
 #include "base/strings/stringprintf.h"
@@ -84,9 +86,7 @@
   IPC_BEGIN_MESSAGE_MAP(AudioInputMessageFilter, message)
     IPC_MESSAGE_HANDLER(AudioInputMsg_NotifyStreamCreated,
                         OnStreamCreated)
-    IPC_MESSAGE_HANDLER(AudioInputMsg_NotifyStreamVolume, OnStreamVolume)
-    IPC_MESSAGE_HANDLER(AudioInputMsg_NotifyStreamStateChanged,
-                        OnStreamStateChanged)
+    IPC_MESSAGE_HANDLER(AudioInputMsg_NotifyStreamError, OnStreamError)
     IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
   return handled;
@@ -145,19 +145,7 @@
   delegate->OnStreamCreated(handle, socket_handle, length, total_segments);
 }
 
-void AudioInputMessageFilter::OnStreamVolume(int stream_id, double volume) {
-  DCHECK(io_task_runner_->BelongsToCurrentThread());
-  media::AudioInputIPCDelegate* delegate = delegates_.Lookup(stream_id);
-  if (!delegate) {
-    DLOG(WARNING) << "Got audio stream event for a non-existent or removed"
-                  << " audio capturer.";
-    return;
-  }
-  delegate->OnVolume(volume);
-}
-
-void AudioInputMessageFilter::OnStreamStateChanged(
-    int stream_id, media::AudioInputIPCDelegateState state) {
+void AudioInputMessageFilter::OnStreamError(int stream_id) {
   DCHECK(io_task_runner_->BelongsToCurrentThread());
   media::AudioInputIPCDelegate* delegate = delegates_.Lookup(stream_id);
   if (!delegate) {
@@ -165,7 +153,7 @@
                   << " audio renderer.";
     return;
   }
-  delegate->OnStateChanged(state);
+  delegate->OnError();
 }
 
 AudioInputMessageFilter::AudioInputIPCImpl::AudioInputIPCImpl(
diff --git a/content/renderer/media/audio_input_message_filter.h b/content/renderer/media/audio_input_message_filter.h
index 337ddb58..4f48bccf 100644
--- a/content/renderer/media/audio_input_message_filter.h
+++ b/content/renderer/media/audio_input_message_filter.h
@@ -75,13 +75,9 @@
                        uint32_t length,
                        uint32_t total_segments);
 
-  // Notification of volume property of an audio input stream.
-  void OnStreamVolume(int stream_id, double volume);
-
   // Received when internal state of browser process' audio input stream has
-  // changed.
-  void OnStreamStateChanged(int stream_id,
-                            media::AudioInputIPCDelegateState state);
+  // encountered an error.
+  void OnStreamError(int stream_id);
 
   // A map of stream ids to delegates.
   IDMap<media::AudioInputIPCDelegate*> delegates_;
diff --git a/content/renderer/pepper/pepper_platform_audio_input.cc b/content/renderer/pepper/pepper_platform_audio_input.cc
index c4db366..b3ca686 100644
--- a/content/renderer/pepper/pepper_platform_audio_input.cc
+++ b/content/renderer/pepper/pepper_platform_audio_input.cc
@@ -113,10 +113,7 @@
   }
 }
 
-void PepperPlatformAudioInput::OnVolume(double volume) {}
-
-void PepperPlatformAudioInput::OnStateChanged(
-    media::AudioInputIPCDelegateState state) {}
+void PepperPlatformAudioInput::OnError() {}
 
 void PepperPlatformAudioInput::OnIPCClosed() { ipc_.reset(); }
 
diff --git a/content/renderer/pepper/pepper_platform_audio_input.h b/content/renderer/pepper/pepper_platform_audio_input.h
index c7b6bc0..f3fe7802 100644
--- a/content/renderer/pepper/pepper_platform_audio_input.h
+++ b/content/renderer/pepper/pepper_platform_audio_input.h
@@ -62,8 +62,7 @@
                        base::SyncSocket::Handle socket_handle,
                        int length,
                        int total_segments) override;
-  void OnVolume(double volume) override;
-  void OnStateChanged(media::AudioInputIPCDelegateState state) override;
+  void OnError() override;
   void OnIPCClosed() override;
 
  protected:
diff --git a/docs/memory-infra/memory_benchmarks.md b/docs/memory-infra/memory_benchmarks.md
new file mode 100644
index 0000000..c33610a
--- /dev/null
+++ b/docs/memory-infra/memory_benchmarks.md
@@ -0,0 +1,210 @@
+# Memory Benchmarks
+
+This document describes benchmarks available to track Chrome's and
+WebView's memory usage, where they live, what they measure, how to run them,
+and on how to diagnose regressions.
+
+[TOC]
+
+## Glossary
+
+*   **User story:** a set of actions to perform on a browser or device (e.g.
+    open google homepage, type "foo", click search, scroll down, visit first
+    result, etc.).
+*   **Metric:** a data aggregation process that takes a Chrome trace as input
+    (produced by a [Telemetry][] run) and produces a set of summary numbers as
+    output (e.g. total GPU memory used).
+*   **Benchmark:** a combination of (one or more) user stories and (one or
+    more) metrics.
+
+[Telemetry]: https://github.com/catapult-project/catapult/blob/master/telemetry/README.md
+
+## System Health
+
+*System health* is an effort to unify top-level benchmarks (as opposite to
+micro-benchmarks and regression tests) that are suitable to capture
+representative user stories.
+
+### Benchmarks
+
+System health memory benchmarks are:
+
+*   [system_health.memory_mobile][system_health] -
+    user stories running on Android devices.
+*   [system_health.memory_desktop][system_health] -
+    user stories running on desktop platforms.
+
+These benchmarks are run continuously on the [chromium.perf][] waterfall,
+collecting and reporting results on the
+[Chrome Performance Dashboard][chromeperf].
+
+Other benchmarks maintained by the memory-infra team are discussed in the
+[appendix](#Other-benchmarks).
+
+[system_health]: https://chromium.googlesource.com/chromium/src/+/master/tools/perf/page_sets/system_health/
+[chromium.perf]: https://build.chromium.org/p/chromium.perf/waterfall
+[chromeperf]: https://chromeperf.appspot.com/report
+
+### User stories
+
+System health user stories are classified by the kind of interactions they
+perform with the browser:
+
+*   `browse` stories navigate to a URL and interact with the page; e.g.
+    scroll, click on elements, navigate to subpages, navigate back.
+*   `load` stories just navigate to a URL and wait for the page to
+    load.
+*   `background` stories navigate to a URL, possibly interact with the
+    page, and then bring another app to the foreground (thus pushing the
+    browser to the background).
+*   `long_running` stories interact with a page for a longer period
+    of time (~5 mins).
+*   `blank` has a single story that just navigates to **about:blank**.
+
+The full name of a story has the form `{interaction}:{category}:{site}` where:
+
+*   `interaction` is one the labels given above;
+*   `category` is used to group together sites with a similar purpose,
+    e.g. `news`, `social`, `tools`;
+*   `site` is a short name identifying the website in which the story mostly
+    takes place, e.g. `cnn`, `facebook`, `gmail`.
+
+For example `browse:news:cnn` and `background:social:facebook` are two system
+health user stories.
+
+Today, for most stories a garbage collection is forced at the end of the
+story and a memory dump is then triggered. Metrics report the values
+obtained from this single measurement.
+
+## Continuous monitoring
+
+![Chrome Performance Dashboard](https://storage.googleapis.com/chromium-docs.appspot.com/79d08f59cf497c761f7099ea427704c14e9afc03.png)
+
+To view data from one of the benchmarks on the
+[Chrome Performance Dashboard][chromeperf] you should select:
+
+*   **Test suite:** The name of a *[benchmark](#Benchmarks)*.
+*   **Bot:** The name of a *platform or device configuration*. Sign in to also
+    see internal bots.
+*   **Subtest (1):** The name of a *[metric](#Understanding-memory-metrics)*.
+*   **Subtest (2):** The name of a *story group*; these have the form
+    `{interaction}_{category}` for system health stories.
+*   **Subtest (3):** The name of a *[user story](#User-stories)*
+    (with `:` replaced by `_`).
+
+## How to run the benchmarks
+
+Benchmarks may be run on a local platform/device or remotely on a try job.
+
+### How to run locally
+
+After building, e.g. `ChromePublic.apk`, you can run a specific system health
+story with the command:
+
+```
+$SRC/tools/perf/run_benchmark run system_health.memory_mobile \
+    --browser android-chromium --story-filter load:search:google
+```
+
+This will run the story with a default of 3 repetitions and produce a
+`results.html` file comparing results from this and any previous benchmark
+runs.
+
+![Example results.html file](https://storage.googleapis.com/chromium-docs.appspot.com/ea60207d9bb4809178fe75923d6d1a2b241170ef.png)
+
+Other useful options for this command are:
+
+*   `--pageset-repeat [n]` - override the default number of repetitions
+*   `--output-format html --output-format json` - select *both* output formats
+     to get individual [trace files][memory-infra] in addition to the
+     `results.html` file.
+*   `--reset-results` - clear results from any previous benchmark runs in the
+    `results.html` file.
+*   `--results-label [label]` - give meaningful names to your benchmark runs,
+    this way it is easier to compare them.
+
+For WebView make sure to [replace the system WebView][webview_install]
+on your device and use `--browser android-webview`.
+
+[webview_install]: https://www.chromium.org/developers/how-tos/build-instructions-android-webview
+
+### How to run a try job
+
+Given a patch on a chromium checkout, try jobs provide a convenient way to
+evaluate its memory implications on devices or platforms which
+may not be immediately available to developers.
+
+To start a try job [upload a CL][contributing] and run the command, e.g.:
+
+```
+$SRC/tools/perf/run_benchmark try android-nexus5 system_health.memory_mobile
+```
+
+This will run all of the system health stories for you, and conveniently
+provide a `results.html` file comparing measurements with/without your patch.
+Options like `--story-filter` and `--pageset-repeat` may also be passed to
+this command.
+
+To see the full list of available try bots run the command:
+
+```
+$SRC/tools/perf/run_benchmark try list
+```
+
+[contributing]: https://www.chromium.org/developers/contributing-code
+
+## Understanding memory metrics
+
+There is a large number of [memory-infra][] metrics, breaking down usage
+attributed to different components and processes.
+
+![memory-infra metrics](https://storage.googleapis.com/chromium-docs.appspot.com/a73239c6367ed0f844500e51ce1e04556cb99b4f.png)
+
+Most memory metrics have the form
+`memory:{browser}:{processes}:{source}:{component}:{kind}`
+where:
+
+*   **browser:** One of `chrome` or `webview`.
+*   **processess:** One of `browser_process`, `renderer_processess`,
+    `gpu_process`, or `all_processess`.
+*   **source:** One of `reported_by_chrome` or `reported_by_os`
+*   **component:** May be a Chrome component, e.g. `skia` or `sqlite`;
+    details about a specific component, e.g. `v8:heap`; or a class of memory
+    as seen by the OS, e.g. `system_memory:native_heap` or `gpu_memory`.
+*   **kind:** The kind of memory being reported. For metrics reported by
+    Chrome this usually is `effective_size` (others are `locked_size`
+    and `allocated_objects_size`); for metrics by the OS this usually is
+    `proportional_resident_size` (others are `peak_resident_size` and
+    `private_dirty_size`).
+
+[memory-infra]: /memory-infra/README.md
+
+## Appendix
+
+### Other benchmarks
+
+Other benchmarks maintained by the memory-infra team are:
+
+*   [memory.dual_browser_test][memory_py] - cycle between doing Google searches
+    on a WebView-based browser (a stand-in for the Google Search app) and
+    loading pages on Chrome. Runs on Android devices only.
+
+    Story groups are either `on_chrome` or `on_webview`, indicating the browser
+    in foreground at the moment when the memory measurement was made.
+
+*   [memory.long_running_dual_browser_test][memory_py] - same as above, but the
+    test is run for 60 iterations keeping both browsers alive for the whole
+    duration of the test and without forcing garbage collection. Intended as a
+    last-resort net to catch memory leaks not apparent on shorter tests.
+
+*   [memory.top_10_mobile][memory_py] - cycle between loading a page on Chrome,
+    pushing the browser to the background, and then back to the foreground.
+    *(To be deprecated in favor of system_health.memory_mobile.)*
+
+    Story groups are either `foreground` or `background` indicating the state
+    of the browser at the time of measurement.
+
+*   [memory.top_10_mobile_stress][memory_py] - same as above, but keeps a single
+    instance of the browser open for 5 repetitions. *(To be deprecated.)*
+
+[memory_py]: https://chromium.googlesource.com/chromium/src/+/master/tools/perf/benchmarks/memory.py
diff --git a/docs/ozone_overview.md b/docs/ozone_overview.md
index af63436..3d070392 100644
--- a/docs/ozone_overview.md
+++ b/docs/ozone_overview.md
@@ -135,15 +135,8 @@
 
 ### Embedded
 
-The following targets are currently working for embedded builds:
-
-* `content_shell`
-* various unit tests
-
-The following targets are currently NOT supported:
-
-* `ash_shell_with_content`
-* `chrome`
+**Warning: Only some targets such as `content_shell` or unit tests are
+currently working for embedded builds.**
 
 To build `content_shell`, do this from the `src` directory:
 
@@ -160,12 +153,10 @@
 ```
 
 ### Linux Desktop - ([waterfall](https://build.chromium.org/p/chromium.fyi/builders/Ozone%20Linux/))
-Support for Linux Desktop is currently [in-progress](https://crbug.com/295089).
 
-The following targets are currently working:
-
-* various unit tests
-* `chrome`
+**Warning: Experimental support for Linux Desktop is available since m57
+but this is still [in development](https://crbug.com/295089) and currently has
+many bugs.**
 
 To build `chrome`, do this from the `src` directory:
 
@@ -177,11 +168,10 @@
 
 ``` shell
 ./out/OzoneLinuxDesktop/chrome --ozone-platform=x11 \
-                               --mash
+                               --mash \
+                               --window-manager=simple_wm
 ```
 
-Note: You may need to apply [this patch](https://codereview.chromium.org/2485673002/) to avoid missing ash resources during chrome execution.
-
 ### GN Configuration notes
 
 You can turn properly implemented ozone platforms on and off by setting the
@@ -259,15 +249,15 @@
 with us on freenode.net, `#ozone-wayland` channel or on `ozone-dev`.
 
 Below are some quick build & run instructions. It is assumed that you are
-launching `chrome` from a Wayland environment such as `weston`. Apply
-[this patch](https://codereview.chromium.org/2485673002/) and execute the
+launching `chrome` from a Wayland environment such as `weston`. Execute the
 following commands:
 
 ``` shell
 gn args out/OzoneWayland --args="use_ozone=true enable_package_mash_services=true"
 ninja -C out/OzoneWayland chrome
 ./out/OzoneWayland/chrome --ozone-platform=wayland \
-                          --mash
+                          --mash \
+                          --window-manager=simple_wm
 ```
 
 ### Caca
diff --git a/ios/chrome/browser/BUILD.gn b/ios/chrome/browser/BUILD.gn
index 4d26fdd2..b72e1fd0 100644
--- a/ios/chrome/browser/BUILD.gn
+++ b/ios/chrome/browser/BUILD.gn
@@ -257,40 +257,6 @@
   ]
 }
 
-source_set("downstream_provider") {
-  sources = [
-    "downstream_chromium_browser_provider.h",
-    "downstream_chromium_browser_provider.mm",
-  ]
-  deps = [
-    ":browser",
-    "//base",
-    "//components/pref_registry",
-    "//components/prefs",
-    "//ios/chrome/browser/autofill:autofill_internal",
-    "//ios/chrome/browser/browser_state",
-    "//ios/chrome/browser/browser_state:browser_state_impl",
-    "//ios/chrome/browser/providers",
-    "//ios/chrome/browser/sync/glue",
-    "//ios/chrome/browser/sync/sessions",
-    "//ios/chrome/browser/tabs",
-    "//ios/chrome/browser/tabs:tabs_internal",
-    "//ios/chrome/browser/ui",
-    "//ios/chrome/browser/ui/webui:webui_internal",
-  ]
-}
-
-source_set("downstream_provider_factory") {
-  sources = [
-    "downstream_chromium_browser_provider_factory.mm",
-  ]
-  deps = [
-    ":downstream_provider",
-    "//base",
-    "//ios/public/provider/chrome/browser",
-  ]
-}
-
 # Clean Skeleton targets
 source_set("browser_clean_skeleton") {
   sources = [
diff --git a/ios/chrome/browser/autofill/autofill_agent.mm b/ios/chrome/browser/autofill/autofill_agent.mm
index ea1e25a9..2fd9f9b7 100644
--- a/ios/chrome/browser/autofill/autofill_agent.mm
+++ b/ios/chrome/browser/autofill/autofill_agent.mm
@@ -635,7 +635,7 @@
                completionHandler:completionHandler];
 }
 
-- (void)webStateDidLoadPage:(web::WebState*)webState {
+- (void)webStateDidLoadPage:(web::WebState*)webState withSuccess:(BOOL)success {
   if (!browserState_->GetPrefs()->GetBoolean(
           autofill::prefs::kAutofillEnabled) ||
       !webState->ContentIsHTML()) {
diff --git a/ios/chrome/browser/autofill/form_input_accessory_view_controller.mm b/ios/chrome/browser/autofill/form_input_accessory_view_controller.mm
index cec559d..e18ea2a 100644
--- a/ios/chrome/browser/autofill/form_input_accessory_view_controller.mm
+++ b/ios/chrome/browser/autofill/form_input_accessory_view_controller.mm
@@ -475,7 +475,7 @@
 #pragma mark -
 #pragma mark CRWWebStateObserver
 
-- (void)webStateDidLoadPage:(web::WebState*)webState {
+- (void)webStateDidLoadPage:(web::WebState*)webState withSuccess:(BOOL)success {
   [self reset];
 }
 
diff --git a/ios/chrome/browser/autofill/form_suggestion_controller.mm b/ios/chrome/browser/autofill/form_suggestion_controller.mm
index de699fe2..9382b3d 100644
--- a/ios/chrome/browser/autofill/form_suggestion_controller.mm
+++ b/ios/chrome/browser/autofill/form_suggestion_controller.mm
@@ -133,7 +133,7 @@
   [self detachFromWebState];
 }
 
-- (void)webStateDidLoadPage:(web::WebState*)webState {
+- (void)webStateDidLoadPage:(web::WebState*)webState withSuccess:(BOOL)success {
   [self processPage:webState];
 }
 
diff --git a/ios/chrome/browser/autofill/form_suggestion_controller_unittest.mm b/ios/chrome/browser/autofill/form_suggestion_controller_unittest.mm
index c44ad27..e6732a0b 100644
--- a/ios/chrome/browser/autofill/form_suggestion_controller_unittest.mm
+++ b/ios/chrome/browser/autofill/form_suggestion_controller_unittest.mm
@@ -250,7 +250,7 @@
 TEST_F(FormSuggestionControllerTest, PageLoadShouldBeIgnoredWhenNotWebScheme) {
   SetUpController(@[]);
   SetCurrentUrl("data:text/html;charset=utf8;base64,");
-  [suggestion_controller_ webStateDidLoadPage:web_state()];
+  [suggestion_controller_ webStateDidLoadPage:web_state() withSuccess:YES];
 
   EXPECT_FALSE(GetSuggestionView(input_accessory_view_));
   EXPECT_OCMOCK_VERIFY(mock_js_suggestion_manager_);
@@ -261,7 +261,7 @@
   SetUpController(@[]);
   SetCurrentUrl("http://foo.com");
   SetContentIsHtml(NO);
-  [suggestion_controller_ webStateDidLoadPage:web_state()];
+  [suggestion_controller_ webStateDidLoadPage:web_state() withSuccess:YES];
 
   EXPECT_FALSE(GetSuggestionView(input_accessory_view_));
   EXPECT_OCMOCK_VERIFY(mock_js_suggestion_manager_);
@@ -276,7 +276,7 @@
 
   // Load the page. The JS should be injected.
   [[mock_js_suggestion_manager_ expect] inject];
-  [suggestion_controller_ webStateDidLoadPage:web_state()];
+  [suggestion_controller_ webStateDidLoadPage:web_state() withSuccess:YES];
   EXPECT_OCMOCK_VERIFY(mock_js_suggestion_manager_);
 
   // Trigger form activity, which should set up the suggestions view.
@@ -290,7 +290,7 @@
 
   // Trigger another page load. The suggestions accessory view should
   // not be present.
-  [accessory_controller_ webStateDidLoadPage:web_state()];
+  [accessory_controller_ webStateDidLoadPage:web_state() withSuccess:YES];
   EXPECT_FALSE(GetSuggestionView(input_accessory_view_));
 }
 
diff --git a/ios/chrome/browser/downstream_chromium_browser_provider.h b/ios/chrome/browser/downstream_chromium_browser_provider.h
deleted file mode 100644
index acfadeb27..0000000
--- a/ios/chrome/browser/downstream_chromium_browser_provider.h
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef IOS_CHROME_BROWSER_DOWNSTREAM_CHROMIUM_BROWSER_PROVIDER_H_
-#define IOS_CHROME_BROWSER_DOWNSTREAM_CHROMIUM_BROWSER_PROVIDER_H_
-
-#include "ios/chrome/browser/providers/chromium_browser_provider.h"
-
-// DownstreamChromiumBrowserProvider contains provider implementations that will
-// eventually move into the upstream ChromiumBrowserProvider, but currently
-// cannot move because they have internal dependencies.
-class DownstreamChromiumBrowserProvider : public ChromiumBrowserProvider {
- public:
-  DownstreamChromiumBrowserProvider();
-  ~DownstreamChromiumBrowserProvider() override;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(DownstreamChromiumBrowserProvider);
-};
-
-#endif  // IOS_CHROME_BROWSER_DOWNSTREAM_CHROMIUM_BROWSER_PROVIDER_H_
diff --git a/ios/chrome/browser/downstream_chromium_browser_provider.mm b/ios/chrome/browser/downstream_chromium_browser_provider.mm
deleted file mode 100644
index 7a2608e..0000000
--- a/ios/chrome/browser/downstream_chromium_browser_provider.mm
+++ /dev/null
@@ -1,9 +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.
-
-#import "ios/chrome/browser/downstream_chromium_browser_provider.h"
-
-DownstreamChromiumBrowserProvider::DownstreamChromiumBrowserProvider() {}
-
-DownstreamChromiumBrowserProvider::~DownstreamChromiumBrowserProvider() {}
diff --git a/ios/chrome/browser/downstream_chromium_browser_provider_factory.mm b/ios/chrome/browser/downstream_chromium_browser_provider_factory.mm
deleted file mode 100644
index 06eb39a..0000000
--- a/ios/chrome/browser/downstream_chromium_browser_provider_factory.mm
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/memory/ptr_util.h"
-#include "ios/chrome/browser/downstream_chromium_browser_provider.h"
-#include "ios/public/provider/chrome/browser/chrome_browser_provider.h"
-
-namespace ios {
-std::unique_ptr<ChromeBrowserProvider> CreateChromeBrowserProvider() {
-  return base::MakeUnique<DownstreamChromiumBrowserProvider>();
-}
-}  // namespace ios
diff --git a/ios/chrome/browser/itunes_links/itunes_links_observer.mm b/ios/chrome/browser/itunes_links/itunes_links_observer.mm
index 3ba6a354..55c7a9d 100644
--- a/ios/chrome/browser/itunes_links/itunes_links_observer.mm
+++ b/ios/chrome/browser/itunes_links/itunes_links_observer.mm
@@ -59,7 +59,7 @@
 
 #pragma mark - CRWWebStateObserver
 
-- (void)webStateDidLoadPage:(web::WebState*)webState {
+- (void)webStateDidLoadPage:(web::WebState*)webState withSuccess:(BOOL)success {
   GURL URL = webState->GetLastCommittedURL();
   NSString* productID = [ITunesLinksObserver productIDFromURL:URL];
   if (productID)
diff --git a/ios/chrome/browser/itunes_links/itunes_links_observer_unittest.mm b/ios/chrome/browser/itunes_links/itunes_links_observer_unittest.mm
index 4045567c..edd1438d 100644
--- a/ios/chrome/browser/itunes_links/itunes_links_observer_unittest.mm
+++ b/ios/chrome/browser/itunes_links/itunes_links_observer_unittest.mm
@@ -33,7 +33,7 @@
     if (expected_product_id)
       [[mocked_store_kit_launcher_ expect] openAppStore:expected_product_id];
     web_state_.SetCurrentURL(GURL(url_string));
-    [link_observer_ webStateDidLoadPage:&web_state_];
+    [link_observer_ webStateDidLoadPage:&web_state_ withSuccess:YES];
     EXPECT_OCMOCK_VERIFY(mocked_store_kit_launcher_);
   }
 
diff --git a/ios/chrome/browser/metrics/first_user_action_recorder.cc b/ios/chrome/browser/metrics/first_user_action_recorder.cc
index aac5e0c..c0790876 100644
--- a/ios/chrome/browser/metrics/first_user_action_recorder.cc
+++ b/ios/chrome/browser/metrics/first_user_action_recorder.cc
@@ -64,7 +64,7 @@
 const char* kNewTaskActions[] = {
     "MobileMenuAllBookmarks",     "MobileMenuHistory",
     "MobileMenuNewIncognitoTab",  "MobileMenuNewTab",
-    "MobileMenuOpenTabs",         "MobileMenuVoiceSearch",
+    "MobileMenuRecentTabs",       "MobileMenuVoiceSearch",
     "MobileNTPBookmark",          "MobileNTPForeignSession",
     "MobileNTPMostVisited",       "MobileNTPShowBookmarks",
     "MobileNTPShowMostVisited",   "MobileNTPShowOpenTabs",
diff --git a/ios/chrome/browser/passwords/password_controller.mm b/ios/chrome/browser/passwords/password_controller.mm
index 98c0d9f0..88e5dba 100644
--- a/ios/chrome/browser/passwords/password_controller.mm
+++ b/ios/chrome/browser/passwords/password_controller.mm
@@ -365,7 +365,7 @@
 #pragma mark -
 #pragma mark CRWWebStateObserver
 
-- (void)webStateDidLoadPage:(web::WebState*)webState {
+- (void)webStateDidLoadPage:(web::WebState*)webState withSuccess:(BOOL)success {
   // Clear per-page state.
   formData_.reset();
 
diff --git a/ios/chrome/browser/passwords/password_controller_unittest.mm b/ios/chrome/browser/passwords/password_controller_unittest.mm
index 9f52d6be..06f7b8d 100644
--- a/ios/chrome/browser/passwords/password_controller_unittest.mm
+++ b/ios/chrome/browser/passwords/password_controller_unittest.mm
@@ -1291,7 +1291,7 @@
 
   web_state.SetContentIsHTML(false);
   web_state.SetCurrentURL(GURL("https://example.com"));
-  [passwordController webStateDidLoadPage:&web_state];
+  [passwordController webStateDidLoadPage:&web_state withSuccess:YES];
 }
 
 // Tests that an HTTP page without a password field does not update the SSL
diff --git a/ios/chrome/browser/passwords/password_generation_agent.mm b/ios/chrome/browser/passwords/password_generation_agent.mm
index d9d1e1c8..57e0a845 100644
--- a/ios/chrome/browser/passwords/password_generation_agent.mm
+++ b/ios/chrome/browser/passwords/password_generation_agent.mm
@@ -334,7 +334,7 @@
 #pragma mark -
 #pragma mark CRWWebStateObserver
 
-- (void)webStateDidLoadPage:(web::WebState*)webState {
+- (void)webStateDidLoadPage:(web::WebState*)webState withSuccess:(BOOL)success {
   [self clearState];
 }
 
diff --git a/ios/chrome/browser/tabs/tab.mm b/ios/chrome/browser/tabs/tab.mm
index dac801e1..72d4d06 100644
--- a/ios/chrome/browser/tabs/tab.mm
+++ b/ios/chrome/browser/tabs/tab.mm
@@ -1374,34 +1374,6 @@
   }
 }
 
-- (void)openURLWithParams:(const web::WebState::OpenURLParams&)params {
-  switch (params.disposition) {
-    case WindowOpenDisposition::NEW_FOREGROUND_TAB:
-    case WindowOpenDisposition::NEW_BACKGROUND_TAB:
-      [parentTabModel_
-          insertOrUpdateTabWithURL:params.url
-                          referrer:params.referrer
-                        transition:params.transition
-                        windowName:nil
-                            opener:self
-                       openedByDOM:NO
-                           atIndex:TabModelConstants::kTabPositionAutomatically
-                      inBackground:(params.disposition ==
-                                    WindowOpenDisposition::NEW_BACKGROUND_TAB)];
-      break;
-    case WindowOpenDisposition::CURRENT_TAB: {
-      web::NavigationManager::WebLoadParams loadParams(params.url);
-      loadParams.referrer = params.referrer;
-      loadParams.transition_type = params.transition;
-      loadParams.is_renderer_initiated = params.is_renderer_initiated;
-      self.navigationManager->LoadURLWithParams(loadParams);
-    } break;
-    default:
-      NOTIMPLEMENTED();
-      break;
-  };
-}
-
 - (BOOL)openExternalURL:(const GURL&)url linkClicked:(BOOL)linkClicked {
   if (!externalAppLauncher_.get())
     externalAppLauncher_.reset([[ExternalAppLauncher alloc] init]);
diff --git a/ios/chrome/browser/translate/js_language_detection_manager_unittest.mm b/ios/chrome/browser/translate/js_language_detection_manager_unittest.mm
index c506eb8..6ec7d42 100644
--- a/ios/chrome/browser/translate/js_language_detection_manager_unittest.mm
+++ b/ios/chrome/browser/translate/js_language_detection_manager_unittest.mm
@@ -6,9 +6,11 @@
 
 #include <string.h>
 
+#include <memory>
+#include <vector>
+
 #include "base/bind.h"
 #include "base/mac/scoped_nsobject.h"
-#include "base/memory/scoped_vector.h"
 #import "base/test/ios/wait_util.h"
 #include "base/values.h"
 #import "ios/chrome/browser/web/chrome_web_test.h"
@@ -272,13 +274,13 @@
   bool CommandReceived(const base::DictionaryValue& command,
                        const GURL&,
                        bool) {
-    commands_received_.push_back(command.DeepCopy());
+    commands_received_.push_back(command.CreateDeepCopy());
     return true;
   }
 
  protected:
   // Received "languageDetection" commands.
-  ScopedVector<base::DictionaryValue> commands_received_;
+  std::vector<std::unique_ptr<base::DictionaryValue>> commands_received_;
 };
 
 // Tests if |__gCrWeb.languageDetection.detectLanguage| correctly informs the
@@ -307,7 +309,7 @@
   InjectJSAndWaitUntilCondition(@"__gCrWeb.languageDetection.detectLanguage()",
                                 commands_recieved_block);
   ASSERT_EQ(1U, commands_received_.size());
-  base::DictionaryValue* value = commands_received_[0];
+  base::DictionaryValue* value = commands_received_[0].get();
   EXPECT_TRUE(value->HasKey("translationAllowed"));
   bool translation_allowed = true;
   value->GetBoolean("translationAllowed", &translation_allowed);
@@ -338,7 +340,7 @@
     return !commands_received_.empty();
   });
   ASSERT_EQ(1U, commands_received_.size());
-  base::DictionaryValue* value = commands_received_[0];
+  base::DictionaryValue* value = commands_received_[0].get();
 
   EXPECT_TRUE(value->HasKey("translationAllowed"));
   EXPECT_TRUE(value->HasKey("captureTextTime"));
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_all_collection_view.mm b/ios/chrome/browser/ui/bookmarks/bookmark_all_collection_view.mm
index b1aacd6..d51506ba8 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_all_collection_view.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_all_collection_view.mm
@@ -4,6 +4,9 @@
 
 #import "ios/chrome/browser/ui/bookmarks/bookmark_all_collection_view.h"
 
+#include <memory>
+#include <vector>
+
 #include "base/logging.h"
 #include "base/mac/objc_property_releaser.h"
 #include "base/mac/scoped_nsobject.h"
@@ -38,7 +41,7 @@
 
 @interface BookmarkAllCollectionView ()<BookmarkPromoCellDelegate> {
   // A vector of vectors. Url nodes are segregated by month of creation.
-  ScopedVector<NodesSection> _nodesSectionVector;
+  std::vector<std::unique_ptr<NodesSection>> _nodesSectionVector;
   // To avoid refreshing the internal model too often.
   UpdateState _updateScheduled;
   base::mac::ObjCPropertyReleaser _propertyReleaser_BookmarkAllCollectionView;
@@ -177,7 +180,7 @@
   // Only remove the node from the list of all nodes. Since we also receive a
   // 'bookmarkNodeChildrenChanged' callback, the collection view will be updated
   // there.
-  for (NodesSection* nodesSection : _nodesSectionVector) {
+  for (const auto& nodesSection : _nodesSectionVector) {
     NodeVector nodeVector = nodesSection->vector;
     // If the node was in _nodesSectionVector, it is now invalid. In that case,
     // remove it from _nodesSectionVector.
@@ -292,7 +295,7 @@
   if ([self shouldShowPromoCell])
     section = 1;
 
-  for (NodesSection* nodesSection : _nodesSectionVector) {
+  for (const auto& nodesSection : _nodesSectionVector) {
     NodeVector nodeVector = nodesSection->vector;
     NSInteger item = 0;
     for (const BookmarkNode* node : nodeVector) {
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h b/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h
index af28381..0ebdfc8 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h
@@ -6,10 +6,11 @@
 #define IOS_CHROME_BROWSER_UI_BOOKMARKS_BOOKMARK_UTILS_IOS_H_
 
 #import <UIKit/UIKit.h>
+
+#include <memory>
 #include <set>
 #include <vector>
 
-#include "base/memory/scoped_vector.h"
 #include "base/strings/string16.h"
 #include "base/time/time.h"
 
@@ -151,8 +152,9 @@
 // NodesSections.
 // Automatically clears, populates and sorts |nodesSectionVector|.
 // This method is not thread safe - it should only be called from the ui thread.
-void segregateNodes(const NodeVector& vector,
-                    ScopedVector<NodesSection>& nodesSectionVector);
+void segregateNodes(
+    const NodeVector& vector,
+    std::vector<std::unique_ptr<NodesSection>>& nodesSectionVector);
 
 #pragma mark - Useful bookmark manipulation.
 
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.mm b/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.mm
index a9cbf46..4c6a27b 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.mm
@@ -5,13 +5,16 @@
 #import "ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h"
 
 #include <stdint.h>
+
 #include <memory>
+#include <vector>
 
 #include "base/hash.h"
 #include "base/i18n/string_compare.h"
 #include "base/mac/bind_objc_block.h"
 #include "base/mac/scoped_nsautorelease_pool.h"
 #include "base/mac/scoped_nsobject.h"
+#include "base/memory/ptr_util.h"
 #include "base/metrics/user_metrics_action.h"
 #include "base/strings/sys_string_conversions.h"
 #include "base/strings/utf_string_conversions.h"
@@ -394,30 +397,9 @@
 
 NodesSection::~NodesSection() {}
 
-// Sorts NodesSection by their time.
-class NodesSectionComparator : public std::binary_function<const NodesSection*,
-                                                           const NodesSection*,
-                                                           bool> {
- public:
-  // Returns true if |n1| preceeds |n2|.
-  bool operator()(const NodesSection* n1, const NodesSection* n2) {
-    return n1->time > n2->time;
-  }
-};
-
-// Sorts bookmark nodes by their creation time.
-class NodeCreationComparator : public std::binary_function<const BookmarkNode*,
-                                                           const BookmarkNode*,
-                                                           bool> {
- public:
-  // Returns true if |n1| preceeds |n2|.
-  bool operator()(const BookmarkNode* n1, const BookmarkNode* n2) {
-    return n1->date_added() > n2->date_added();
-  }
-};
-
-void segregateNodes(const NodeVector& vector,
-                    ScopedVector<NodesSection>& nodesSectionVector) {
+void segregateNodes(
+    const NodeVector& vector,
+    std::vector<std::unique_ptr<NodesSection>>& nodesSectionVector) {
   nodesSectionVector.clear();
 
   // Make a localized date formatter.
@@ -436,7 +418,7 @@
     const std::string timeRepresentation = base::SysNSStringToUTF8(dateString);
 
     BOOL found = NO;
-    for (NodesSection* nodesSection : nodesSectionVector) {
+    for (const auto& nodesSection : nodesSectionVector) {
       if (nodesSection->timeRepresentation == timeRepresentation) {
         nodesSection->vector.push_back(node);
         found = YES;
@@ -448,21 +430,27 @@
       continue;
 
     // No NodesSection found.
-    NodesSection* nodesSection = new NodesSection;
+    auto nodesSection = base::MakeUnique<NodesSection>();
     nodesSection->time = dateAdded;
     nodesSection->timeRepresentation = timeRepresentation;
     nodesSection->vector.push_back(node);
-    nodesSectionVector.push_back(nodesSection);
+    nodesSectionVector.push_back(std::move(nodesSection));
   }
 
   // Sort the NodesSections.
   std::sort(nodesSectionVector.begin(), nodesSectionVector.end(),
-            NodesSectionComparator());
+            [](const std::unique_ptr<NodesSection>& n1,
+               const std::unique_ptr<NodesSection>& n2) {
+              return n1->time > n2->time;
+            });
 
   // For each NodesSection, sort the nodes inside.
-  for (NodesSection* nodesSection : nodesSectionVector)
+  for (const auto& nodesSection : nodesSectionVector) {
     std::sort(nodesSection->vector.begin(), nodesSection->vector.end(),
-              NodeCreationComparator());
+              [](const BookmarkNode* n1, const BookmarkNode* n2) {
+                return n1->date_added() > n2->date_added();
+              });
+  }
 }
 
 #pragma mark - Useful bookmark manipulation.
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios_unittest.mm b/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios_unittest.mm
index c75d5bd..841affa 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios_unittest.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios_unittest.mm
@@ -2,6 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <memory>
+#include <vector>
+
 #include "base/strings/sys_string_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
@@ -62,27 +65,27 @@
   toSort.push_back(f2a);
   toSort.push_back(f2b);
 
-  ScopedVector<NodesSection> nodesSectionVector;
+  std::vector<std::unique_ptr<NodesSection>> nodesSectionVector;
   bookmark_utils_ios::segregateNodes(toSort, nodesSectionVector);
 
   // Expect the nodes to be sorted in reverse chronological order, grouped by
   // month.
   ASSERT_EQ(nodesSectionVector.size(), 4u);
-  NodesSection* section = nodesSectionVector[0];
+  NodesSection* section = nodesSectionVector[0].get();
   ASSERT_EQ(section->vector.size(), 1u);
   EXPECT_EQ(section->vector[0], f2a);
 
-  section = nodesSectionVector[1];
+  section = nodesSectionVector[1].get();
   ASSERT_EQ(section->vector.size(), 2u);
   EXPECT_EQ(section->vector[0], b);
   EXPECT_EQ(section->vector[1], a);
 
-  section = nodesSectionVector[2];
+  section = nodesSectionVector[2].get();
   ASSERT_EQ(section->vector.size(), 2u);
   EXPECT_EQ(section->vector[0], f1b);
   EXPECT_EQ(section->vector[1], f1a);
 
-  section = nodesSectionVector[3];
+  section = nodesSectionVector[3].get();
   ASSERT_EQ(section->vector.size(), 1u);
   EXPECT_EQ(section->vector[0], f2b);
 }
diff --git a/ios/chrome/browser/ui/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view_controller.mm
index dba26efc..96a7e13 100644
--- a/ios/chrome/browser/ui/browser_view_controller.mm
+++ b/ios/chrome/browser/ui/browser_view_controller.mm
@@ -687,6 +687,8 @@
 - (void)showSnackbar:(NSString*)message;
 // Induces an intentional crash in the browser process.
 - (void)induceBrowserCrash;
+// Returns Tab that corresponds to the given |webState|.
+- (Tab*)tabForWebState:(web::WebState*)webState;
 // Saves the image or display error message, based on privacy settings.
 - (void)managePermissionAndSaveImage:(NSData*)data;
 // Saves the image. In order to keep the metadata of the image, the image is
@@ -2363,6 +2365,37 @@
 
 #pragma mark - CRWWebStateDelegate methods.
 
+- (web::WebState*)webState:(web::WebState*)webState
+         openURLWithParams:(const web::WebState::OpenURLParams&)params {
+  switch (params.disposition) {
+    case WindowOpenDisposition::NEW_FOREGROUND_TAB:
+    case WindowOpenDisposition::NEW_BACKGROUND_TAB: {
+      Tab* tab = [[self tabModel]
+          insertOrUpdateTabWithURL:params.url
+                          referrer:params.referrer
+                        transition:params.transition
+                        windowName:nil
+                            opener:[self tabForWebState:webState]
+                       openedByDOM:NO
+                           atIndex:TabModelConstants::kTabPositionAutomatically
+                      inBackground:(params.disposition ==
+                                    WindowOpenDisposition::NEW_BACKGROUND_TAB)];
+      return tab.webState;
+    }
+    case WindowOpenDisposition::CURRENT_TAB: {
+      web::NavigationManager::WebLoadParams loadParams(params.url);
+      loadParams.referrer = params.referrer;
+      loadParams.transition_type = params.transition;
+      loadParams.is_renderer_initiated = params.is_renderer_initiated;
+      webState->GetNavigationManager()->LoadURLWithParams(loadParams);
+      return webState;
+    }
+    default:
+      NOTIMPLEMENTED();
+      return nullptr;
+  };
+}
+
 - (void)webState:(web::WebState*)webState didChangeProgress:(double)progress {
   if (webState == [_model currentTab].webState) {
     // TODO(crbug.com/546406): It is probably possible to do something smarter,
@@ -3681,6 +3714,14 @@
   return [[_model currentTab] webState];
 }
 
+- (Tab*)tabForWebState:(web::WebState*)webState {
+  for (Tab* tab in _model.get()) {
+    if (tab.webState == webState)
+      return tab;
+  }
+  return nil;
+}
+
 // This is called from within an animation block.
 - (void)toolbarHeightChanged {
   if ([self headerHeight] != 0) {
diff --git a/ios/chrome/browser/ui/settings/save_passwords_collection_view_controller.mm b/ios/chrome/browser/ui/settings/save_passwords_collection_view_controller.mm
index 32a5317..3f27c1d2 100644
--- a/ios/chrome/browser/ui/settings/save_passwords_collection_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/save_passwords_collection_view_controller.mm
@@ -5,6 +5,7 @@
 #import "ios/chrome/browser/ui/settings/save_passwords_collection_view_controller.h"
 
 #include <memory>
+#include <vector>
 
 #include "base/ios/ios_util.h"
 #import "base/ios/weak_nsobject.h"
@@ -12,7 +13,7 @@
 #include "base/mac/foundation_util.h"
 #import "base/mac/objc_property_releaser.h"
 #import "base/mac/scoped_nsobject.h"
-#include "base/memory/scoped_vector.h"
+#include "base/memory/ptr_util.h"
 #include "base/numerics/safe_conversions.h"
 #include "base/strings/sys_string_conversions.h"
 #include "base/strings/utf_string_conversions.h"
@@ -144,13 +145,13 @@
   std::unique_ptr<password_manager::SavePasswordsConsumer>
       blacklistPasswordsConsumer_;
   // The list of the user's saved passwords.
-  ScopedVector<autofill::PasswordForm> savedForms_;
+  std::vector<std::unique_ptr<autofill::PasswordForm>> savedForms_;
   // The list of the user's blacklisted sites.
-  ScopedVector<autofill::PasswordForm> blacklistedForms_;
+  std::vector<std::unique_ptr<autofill::PasswordForm>> blacklistedForms_;
   // Deletion of password being asynchronous, and the method taking a reference
   // to the PasswordForm, the PasswordForm must outlive the calls to
   // RemoveLogin. This vector will ensure this.
-  ScopedVector<autofill::PasswordForm> deletedForms_;
+  std::vector<std::unique_ptr<autofill::PasswordForm>> deletedForms_;
   // The current Chrome browser state.
   ios::ChromeBrowserState* browserState_;
   // Object storing the time of the previous successful re-authentication.
@@ -235,9 +236,8 @@
           l10n_util::GetNSString(IDS_PASSWORD_MANAGER_SHOW_PASSWORDS_TAB_TITLE);
       [model setHeader:headerItem
           forSectionWithIdentifier:SectionIdentifierSavedPasswords];
-      for (size_t i = 0; i < savedForms_.size(); ++i) {
-        autofill::PasswordForm* form = savedForms_[i];
-        [model addItem:[self savedFormItemWithForm:form]
+      for (const auto& form : savedForms_) {
+        [model addItem:[self savedFormItemWithForm:form.get()]
             toSectionWithIdentifier:SectionIdentifierSavedPasswords];
       }
     }
@@ -249,9 +249,8 @@
           l10n_util::GetNSString(IDS_PASSWORD_MANAGER_EXCEPTIONS_TAB_TITLE);
       [model setHeader:headerItem
           forSectionWithIdentifier:SectionIdentifierBlacklist];
-      for (size_t i = 0; i < blacklistedForms_.size(); ++i) {
-        autofill::PasswordForm* form = blacklistedForms_[i];
-        [model addItem:[self blacklistedFormItemWithForm:form]
+      for (const auto& form : blacklistedForms_) {
+        [model addItem:[self blacklistedFormItemWithForm:form.get()]
             toSectionWithIdentifier:SectionIdentifierBlacklist];
       }
     }
@@ -447,11 +446,11 @@
     (const std::vector<std::unique_ptr<autofill::PasswordForm>>&)result {
   for (auto it = result.begin(); it != result.end(); ++it) {
     // PasswordForm is needed when user wants to delete the site/password.
-    autofill::PasswordForm* form = new autofill::PasswordForm(**it);
+    auto form = base::MakeUnique<autofill::PasswordForm>(**it);
     if (form->blacklisted_by_user)
-      blacklistedForms_.push_back(form);
+      blacklistedForms_.push_back(std::move(form));
     else
-      savedForms_.push_back(form);
+      savedForms_.push_back(std::move(form));
   }
 
   [self updateEditButton];
@@ -484,7 +483,7 @@
               SectionIdentifierSavedPasswords);
     if (experimental_flags::IsViewCopyPasswordsEnabled()) {
       DCHECK_LT(base::checked_cast<size_t>(indexPath.item), savedForms_.size());
-      autofill::PasswordForm* form = savedForms_[indexPath.item];
+      autofill::PasswordForm* form = savedForms_[indexPath.item].get();
       NSString* username = base::SysUTF16ToNSString(form->username_value);
       NSString* password = base::SysUTF16ToNSString(form->password_value);
       NSString* origin =
@@ -531,13 +530,13 @@
     unsigned int formIndex = (unsigned int)indexPath.item;
     // Adjust index to account for deleted items.
     formIndex -= blacklisted ? blacklistedDeleted : passwordsDeleted;
-    ScopedVector<autofill::PasswordForm>& forms =
-        blacklisted ? blacklistedForms_ : savedForms_;
+    auto& forms = blacklisted ? blacklistedForms_ : savedForms_;
     DCHECK_LT(formIndex, forms.size());
     auto formIterator = forms.begin() + formIndex;
-    passwordStore_->RemoveLogin(**formIterator);
-    deletedForms_.push_back(*formIterator);
-    forms.weak_erase(formIterator);
+    std::unique_ptr<autofill::PasswordForm> form = std::move(*formIterator);
+    forms.erase(formIterator);
+    passwordStore_->RemoveLogin(*form);
+    deletedForms_.push_back(std::move(form));
     if (blacklisted) {
       ++blacklistedDeleted;
     } else {
@@ -597,7 +596,7 @@
   passwordStore_->RemoveLogin(form);
   for (auto it = savedForms_.begin(); it != savedForms_.end(); ++it) {
     if (**it == form) {
-      savedForms_.weak_erase(it);
+      savedForms_.erase(it);
       return;
     }
   }
diff --git a/ios/chrome/browser/ui/toolbar/toolbar_controller.mm b/ios/chrome/browser/ui/toolbar/toolbar_controller.mm
index a4bc62b5..a19efd3c 100644
--- a/ios/chrome/browser/ui/toolbar/toolbar_controller.mm
+++ b/ios/chrome/browser/ui/toolbar/toolbar_controller.mm
@@ -214,7 +214,8 @@
   base::scoped_nsobject<UIButton> stackButton_;
   base::scoped_nsobject<UIButton> shareButton_;
   base::scoped_nsobject<NSArray> standardButtons_;
-  std::unique_ptr<ToolsMenuButtonObserverBridge> toolsMenuButtonObserverBridge_;
+  base::scoped_nsobject<ToolsMenuButtonObserverBridge>
+      toolsMenuButtonObserverBridge_;
   ToolbarControllerStyle style_;
 
   // The following is nil if not visible.
@@ -249,10 +250,11 @@
 
 - (void)setReadingListModel:(ReadingListModel*)readingListModel {
   readingListModel_ = readingListModel;
-  if (readingListModel_)
-    toolsMenuButtonObserverBridge_ =
-        base::MakeUnique<ToolsMenuButtonObserverBridge>(readingListModel_,
-                                                        toolsMenuButton_);
+  if (readingListModel_) {
+    toolsMenuButtonObserverBridge_.reset([[ToolsMenuButtonObserverBridge alloc]
+        initWithModel:readingListModel_
+        toolbarButton:toolsMenuButton_]);
+  }
 }
 
 - (instancetype)initWithStyle:(ToolbarControllerStyle)style {
diff --git a/ios/chrome/browser/ui/toolbar/toolbar_coordinator.mm b/ios/chrome/browser/ui/toolbar/toolbar_coordinator.mm
index b684843..c65823ea 100644
--- a/ios/chrome/browser/ui/toolbar/toolbar_coordinator.mm
+++ b/ios/chrome/browser/ui/toolbar/toolbar_coordinator.mm
@@ -39,7 +39,7 @@
 
 #pragma mark - CRWWebStateObserver
 
-- (void)webStateDidLoadPage:(web::WebState*)webState {
+- (void)webStateDidLoadPage:(web::WebState*)webState withSuccess:(BOOL)success {
   const GURL& pageURL = webState->GetVisibleURL();
   [self.viewController
       setCurrentPageText:base::SysUTF8ToNSString(pageURL.spec())];
diff --git a/ios/chrome/browser/ui/toolbar/toolbar_tools_menu_button.h b/ios/chrome/browser/ui/toolbar/toolbar_tools_menu_button.h
index 252e8d76..433719d 100644
--- a/ios/chrome/browser/ui/toolbar/toolbar_tools_menu_button.h
+++ b/ios/chrome/browser/ui/toolbar/toolbar_tools_menu_button.h
@@ -28,8 +28,9 @@
 // Informs the button that the Tools Menu's visibility is |toolsMenuVisible|.
 - (void)setToolsMenuIsVisible:(BOOL)toolsMenuVisible;
 
-// Notifies the button that the Reading List's unread item count changed.
-- (void)setReadingListContainsUnreadItems:(BOOL)readingListContainsUnreadItems;
+// Notifies the button should alert user to the presence of reading list unseen
+// items.
+- (void)setReadingListContainsUnseenItems:(BOOL)readingListContainsUnseenItems;
 
 @end
 
diff --git a/ios/chrome/browser/ui/toolbar/toolbar_tools_menu_button.mm b/ios/chrome/browser/ui/toolbar/toolbar_tools_menu_button.mm
index de0a523..29de8ed 100644
--- a/ios/chrome/browser/ui/toolbar/toolbar_tools_menu_button.mm
+++ b/ios/chrome/browser/ui/toolbar/toolbar_tools_menu_button.mm
@@ -18,8 +18,8 @@
   ToolbarControllerStyle style_;
   // Whether the tools menu is visible.
   BOOL toolsMenuVisible_;
-  // Whether the reading list contains unread items.
-  BOOL readingListContainsUnreadItems_;
+  // Whether the reading list contains unseen items.
+  BOOL readingListContainsUnseenItems_;
 }
 @end
 
@@ -48,15 +48,15 @@
   [self updateTintOfButton];
 }
 
-- (void)setReadingListContainsUnreadItems:(BOOL)readingListContainsUnreadItems {
-  readingListContainsUnreadItems_ = readingListContainsUnreadItems;
+- (void)setReadingListContainsUnseenItems:(BOOL)readingListContainsUnseenItems {
+  readingListContainsUnseenItems_ = readingListContainsUnseenItems;
   [self updateTintOfButton];
 }
 
 #pragma mark - Private
 
 - (void)updateTintOfButton {
-  if (toolsMenuVisible_ || readingListContainsUnreadItems_) {
+  if (toolsMenuVisible_ || readingListContainsUnseenItems_) {
     [self setTintColor:toolbar::HighlighButtonTint(style_)
               forState:UIControlStateNormal];
   } else {
diff --git a/ios/chrome/browser/ui/toolbar/tools_menu_button_observer_bridge.h b/ios/chrome/browser/ui/toolbar/tools_menu_button_observer_bridge.h
index 7105cca..01b9b6e 100644
--- a/ios/chrome/browser/ui/toolbar/tools_menu_button_observer_bridge.h
+++ b/ios/chrome/browser/ui/toolbar/tools_menu_button_observer_bridge.h
@@ -8,30 +8,21 @@
 #import <UIKit/UIKit.h>
 
 #import "base/mac/scoped_nsobject.h"
-#include "components/reading_list/ios/reading_list_model_observer.h"
+#include "components/reading_list/ios/reading_list_model_bridge_observer.h"
 
 @class ToolbarToolsMenuButton;
 
-// C++ bridge informing a ToolbarToolsMenuButton whether the Reading List Model
-// contains unread items.
-class ToolsMenuButtonObserverBridge : public ReadingListModelObserver {
- public:
-  // Creates the bridge to the ToolbarToolsMenuButton |button|.
-  ToolsMenuButtonObserverBridge(ReadingListModel* readingListModel,
-                                ToolbarToolsMenuButton* button);
+// Objective-C bridge informing a ToolbarToolsMenuButton whether the Reading
+// List Model contains unseen items.
+@interface ToolsMenuButtonObserverBridge
+    : NSObject<ReadingListModelBridgeObserver>
 
-  ~ToolsMenuButtonObserverBridge() final;
+// Creates the bridge to the ToolbarToolsMenuButton |button|.
+- (instancetype)initWithModel:(ReadingListModel*)readingListModel
+                toolbarButton:(ToolbarToolsMenuButton*)button
+    NS_DESIGNATED_INITIALIZER;
 
-  // ReadingListModelObserver implementation.
-  void ReadingListModelLoaded(const ReadingListModel* model) override;
-  void ReadingListDidApplyChanges(ReadingListModel* model) override;
-
- private:
-  // Notify the ToolbarToolsMenuButton of whether the reading list contains
-  // unread items.
-  void UpdateButtonWithModel(const ReadingListModel* model);
-  ReadingListModel* readingListModel_;
-  base::scoped_nsobject<ToolbarToolsMenuButton> button_;
-};
+- (instancetype)init NS_UNAVAILABLE;
+@end
 
 #endif  // IOS_CHROME_BROWSER_UI_TOOLBAR_TOOLS_MENU_BUTTON_OBSERVER_BRIDGE_H_
diff --git a/ios/chrome/browser/ui/toolbar/tools_menu_button_observer_bridge.mm b/ios/chrome/browser/ui/toolbar/tools_menu_button_observer_bridge.mm
index 56367651..aed29ae 100644
--- a/ios/chrome/browser/ui/toolbar/tools_menu_button_observer_bridge.mm
+++ b/ios/chrome/browser/ui/toolbar/tools_menu_button_observer_bridge.mm
@@ -4,31 +4,60 @@
 
 #import "ios/chrome/browser/ui/toolbar/tools_menu_button_observer_bridge.h"
 
+#include "base/logging.h"
+#include "base/memory/ptr_util.h"
 #include "components/reading_list/ios/reading_list_model.h"
 #import "ios/chrome/browser/ui/toolbar/toolbar_tools_menu_button.h"
 
-ToolsMenuButtonObserverBridge::ToolsMenuButtonObserverBridge(
-    ReadingListModel* readingListModel,
-    ToolbarToolsMenuButton* button)
-    : readingListModel_(readingListModel), button_([button retain]) {
-  readingListModel_->AddObserver(this);
-};
+@interface ToolsMenuButtonObserverBridge ()
+- (void)updateButtonWithModel:(const ReadingListModel*)model;
+- (void)buttonPressed:(UIButton*)sender;
+@end
 
-ToolsMenuButtonObserverBridge::~ToolsMenuButtonObserverBridge() {
-  readingListModel_->RemoveObserver(this);
+@implementation ToolsMenuButtonObserverBridge {
+  base::scoped_nsobject<ToolbarToolsMenuButton> _button;
+  ReadingListModel* _model;
+  std::unique_ptr<ReadingListModelBridge> _modelBridge;
 }
 
-void ToolsMenuButtonObserverBridge::ReadingListModelLoaded(
-    const ReadingListModel* model) {
-  UpdateButtonWithModel(model);
-}
-void ToolsMenuButtonObserverBridge::ReadingListDidApplyChanges(
-    ReadingListModel* model) {
-  UpdateButtonWithModel(model);
+- (instancetype)initWithModel:(ReadingListModel*)readingListModel
+                toolbarButton:(ToolbarToolsMenuButton*)button {
+  self = [super init];
+  if (self) {
+    _button.reset([button retain]);
+    _model = readingListModel;
+    [_button addTarget:self
+                  action:@selector(buttonPressed:)
+        forControlEvents:UIControlEventTouchUpInside];
+    _modelBridge = base::MakeUnique<ReadingListModelBridge>(self, _model);
+  }
+  return self;
 }
 
-void ToolsMenuButtonObserverBridge::UpdateButtonWithModel(
-    const ReadingListModel* model) {
-  bool readingListContainsUnreadItems = model->unread_size() > 0;
-  [button_ setReadingListContainsUnreadItems:readingListContainsUnreadItems];
+- (void)readingListModelLoaded:(const ReadingListModel*)model {
+  [self updateButtonWithModel:model];
 }
+
+- (void)readingListModelDidApplyChanges:(const ReadingListModel*)model {
+  [self updateButtonWithModel:model];
+}
+
+- (void)readingListModelBeingDeleted:(const ReadingListModel*)model {
+  DCHECK(model == _model);
+  _model = nullptr;
+}
+
+- (void)updateButtonWithModel:(const ReadingListModel*)model {
+  DCHECK(model == _model);
+  BOOL readingListContainsUnseenItems = model->GetLocalUnseenFlag();
+  [_button setReadingListContainsUnseenItems:readingListContainsUnseenItems];
+}
+
+- (void)buttonPressed:(UIButton*)sender {
+  if (_model) {
+    _model->ResetLocalUnseenFlag();
+  }
+  [_button setReadingListContainsUnseenItems:NO];
+}
+
+@end
diff --git a/ios/chrome/browser/ui/tools_menu/tools_popup_controller.mm b/ios/chrome/browser/ui/tools_menu/tools_popup_controller.mm
index 8b26faa9a..837a52b 100644
--- a/ios/chrome/browser/ui/tools_menu/tools_popup_controller.mm
+++ b/ios/chrome/browser/ui/tools_menu/tools_popup_controller.mm
@@ -203,8 +203,7 @@
       base::RecordAction(UserMetricsAction("MobileMenuHistory"));
       break;
     case IDC_SHOW_OTHER_DEVICES:
-      // "Open Tabs" is the original name of the "Other Devices" menu item.
-      base::RecordAction(UserMetricsAction("MobileMenuOpenTabs"));
+      base::RecordAction(UserMetricsAction("MobileMenuRecentTabs"));
       break;
     case IDC_STOP:
       base::RecordAction(UserMetricsAction("MobileMenuStop"));
diff --git a/ios/chrome/browser/ui/webui/crashes_ui.cc b/ios/chrome/browser/ui/webui/crashes_ui.cc
index 269baea..9cf7168 100644
--- a/ios/chrome/browser/ui/webui/crashes_ui.cc
+++ b/ios/chrome/browser/ui/webui/crashes_ui.cc
@@ -9,6 +9,7 @@
 #include "base/bind.h"
 #include "base/bind_helpers.h"
 #include "base/macros.h"
+#include "base/memory/ptr_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/sys_info.h"
 #include "base/values.h"
@@ -146,7 +147,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 CrashesUI::CrashesUI(web::WebUIIOS* web_ui) : web::WebUIIOSController(web_ui) {
-  web_ui->AddMessageHandler(new CrashesDOMHandler());
+  web_ui->AddMessageHandler(base::MakeUnique<CrashesDOMHandler>());
 
   // Set up the chrome://crashes/ source.
   web::WebUIIOSDataSource::Add(ios::ChromeBrowserState::FromWebUIIOS(web_ui),
diff --git a/ios/chrome/browser/ui/webui/flags_ui.cc b/ios/chrome/browser/ui/webui/flags_ui.cc
index 1ffd385..f9246df 100644
--- a/ios/chrome/browser/ui/webui/flags_ui.cc
+++ b/ios/chrome/browser/ui/webui/flags_ui.cc
@@ -9,6 +9,7 @@
 #include "base/bind.h"
 #include "base/bind_helpers.h"
 #include "base/macros.h"
+#include "base/memory/ptr_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
 #include "components/flags_ui/flags_ui_constants.h"
@@ -212,7 +213,7 @@
 
 void BaseFlagsUI::Initialize(web::WebUIIOS* web_ui, FlagsUIKind flags_ui_kind) {
   FlagsDOMHandler* handler = new FlagsDOMHandler();
-  web_ui->AddMessageHandler(handler);
+  web_ui->AddMessageHandler(base::WrapUnique(handler));
 
   flags_ui::FlagAccess flag_access = flags_ui::kOwnerAccessToFlags;
   if (flags_ui_kind == FLAGS_UI_APPLE)
diff --git a/ios/chrome/browser/ui/webui/gcm/gcm_internals_ui.cc b/ios/chrome/browser/ui/webui/gcm/gcm_internals_ui.cc
index 0d69bda..2464355b 100644
--- a/ios/chrome/browser/ui/webui/gcm/gcm_internals_ui.cc
+++ b/ios/chrome/browser/ui/webui/gcm/gcm_internals_ui.cc
@@ -9,6 +9,7 @@
 #include "base/bind.h"
 #include "base/bind_helpers.h"
 #include "base/macros.h"
+#include "base/memory/ptr_util.h"
 #include "base/memory/weak_ptr.h"
 #include "base/values.h"
 #include "components/gcm_driver/gcm_client.h"
@@ -171,7 +172,7 @@
   web::WebUIIOSDataSource::Add(ios::ChromeBrowserState::FromWebUIIOS(web_ui),
                                html_source);
 
-  web_ui->AddMessageHandler(new GcmInternalsUIMessageHandler());
+  web_ui->AddMessageHandler(base::MakeUnique<GcmInternalsUIMessageHandler>());
 }
 
 GCMInternalsUI::~GCMInternalsUI() {}
diff --git a/ios/chrome/browser/ui/webui/net_export/net_export_ui.cc b/ios/chrome/browser/ui/webui/net_export/net_export_ui.cc
index 3fbcb06b..7e2d465 100644
--- a/ios/chrome/browser/ui/webui/net_export/net_export_ui.cc
+++ b/ios/chrome/browser/ui/webui/net_export/net_export_ui.cc
@@ -10,6 +10,7 @@
 #include "base/bind.h"
 #include "base/location.h"
 #include "base/macros.h"
+#include "base/memory/ptr_util.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
@@ -244,7 +245,7 @@
 
 NetExportUI::NetExportUI(web::WebUIIOS* web_ui)
     : web::WebUIIOSController(web_ui) {
-  web_ui->AddMessageHandler(new NetExportMessageHandler());
+  web_ui->AddMessageHandler(base::MakeUnique<NetExportMessageHandler>());
   web::WebUIIOSDataSource::Add(ios::ChromeBrowserState::FromWebUIIOS(web_ui),
                                CreateNetExportHTMLSource());
 }
diff --git a/ios/chrome/browser/ui/webui/ntp_tiles_internals_ui.cc b/ios/chrome/browser/ui/webui/ntp_tiles_internals_ui.cc
index 554f34b83..ecf5386 100644
--- a/ios/chrome/browser/ui/webui/ntp_tiles_internals_ui.cc
+++ b/ios/chrome/browser/ui/webui/ntp_tiles_internals_ui.cc
@@ -4,6 +4,7 @@
 
 #include "ios/chrome/browser/ui/webui/ntp_tiles_internals_ui.h"
 
+#include "base/memory/ptr_util.h"
 #include "components/grit/components_resources.h"
 #include "components/ntp_tiles/field_trial.h"
 #include "components/ntp_tiles/most_visited_sites.h"
@@ -112,7 +113,8 @@
     : web::WebUIIOSController(web_ui) {
   web::WebUIIOSDataSource::Add(ios::ChromeBrowserState::FromWebUIIOS(web_ui),
                                CreateNTPTilesInternalsHTMLSource());
-  web_ui->AddMessageHandler(new IOSNTPTilesInternalsMessageHandlerBridge);
+  web_ui->AddMessageHandler(
+      base::MakeUnique<IOSNTPTilesInternalsMessageHandlerBridge>());
 }
 
 NTPTilesInternalsUI::~NTPTilesInternalsUI() {}
diff --git a/ios/chrome/browser/ui/webui/omaha_ui.cc b/ios/chrome/browser/ui/webui/omaha_ui.cc
index 6560ba9..e317113 100644
--- a/ios/chrome/browser/ui/webui/omaha_ui.cc
+++ b/ios/chrome/browser/ui/webui/omaha_ui.cc
@@ -4,6 +4,7 @@
 
 #include "ios/chrome/browser/ui/webui/omaha_ui.h"
 
+#include "base/memory/ptr_util.h"
 #include "base/memory/weak_ptr.h"
 #include "base/values.h"
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
@@ -81,7 +82,7 @@
 
 // OmahaUI
 OmahaUI::OmahaUI(web::WebUIIOS* web_ui) : WebUIIOSController(web_ui) {
-  web_ui->AddMessageHandler(new OmahaDOMHandler());
+  web_ui->AddMessageHandler(base::MakeUnique<OmahaDOMHandler>());
 
   // Set up the chrome://omaha/ source.
   ios::ChromeBrowserState* browser_state =
diff --git a/ios/chrome/browser/ui/webui/physical_web_ui.cc b/ios/chrome/browser/ui/webui/physical_web_ui.cc
index d5a6127c..98a5ccef 100644
--- a/ios/chrome/browser/ui/webui/physical_web_ui.cc
+++ b/ios/chrome/browser/ui/webui/physical_web_ui.cc
@@ -5,6 +5,7 @@
 #include "ios/chrome/browser/ui/webui/physical_web_ui.h"
 
 #include "base/macros.h"
+#include "base/memory/ptr_util.h"
 #include "base/metrics/user_metrics.h"
 #include "components/grit/components_resources.h"
 #include "components/physical_web/data_source/physical_web_data_source.h"
@@ -96,8 +97,7 @@
 
 PhysicalWebUI::PhysicalWebUI(web::WebUIIOS* web_ui)
     : web::WebUIIOSController(web_ui) {
-  PhysicalWebDOMHandler* handler = new PhysicalWebDOMHandler();
-  web_ui->AddMessageHandler(handler);
+  web_ui->AddMessageHandler(base::MakeUnique<PhysicalWebDOMHandler>());
 
   web::WebUIIOSDataSource::Add(ios::ChromeBrowserState::FromWebUIIOS(web_ui),
                                CreatePhysicalWebUIDataSource());
diff --git a/ios/chrome/browser/ui/webui/popular_sites_internals_ui.cc b/ios/chrome/browser/ui/webui/popular_sites_internals_ui.cc
index c22c471..e07a780 100644
--- a/ios/chrome/browser/ui/webui/popular_sites_internals_ui.cc
+++ b/ios/chrome/browser/ui/webui/popular_sites_internals_ui.cc
@@ -4,6 +4,7 @@
 
 #include "ios/chrome/browser/ui/webui/popular_sites_internals_ui.h"
 
+#include "base/memory/ptr_util.h"
 #include "components/grit/components_resources.h"
 #include "components/ntp_tiles/popular_sites.h"
 #include "components/ntp_tiles/webui/popular_sites_internals_message_handler.h"
@@ -94,7 +95,8 @@
     : web::WebUIIOSController(web_ui) {
   web::WebUIIOSDataSource::Add(ios::ChromeBrowserState::FromWebUIIOS(web_ui),
                                CreatePopularSitesInternalsHTMLSource());
-  web_ui->AddMessageHandler(new IOSPopularSitesInternalsMessageHandlerBridge);
+  web_ui->AddMessageHandler(
+      base::MakeUnique<IOSPopularSitesInternalsMessageHandlerBridge>());
 }
 
 PopularSitesInternalsUI::~PopularSitesInternalsUI() {}
diff --git a/ios/chrome/browser/ui/webui/sync_internals/sync_internals_ui.cc b/ios/chrome/browser/ui/webui/sync_internals/sync_internals_ui.cc
index f54f5c88..e5adf75 100644
--- a/ios/chrome/browser/ui/webui/sync_internals/sync_internals_ui.cc
+++ b/ios/chrome/browser/ui/webui/sync_internals/sync_internals_ui.cc
@@ -4,6 +4,7 @@
 
 #include "ios/chrome/browser/ui/webui/sync_internals/sync_internals_ui.h"
 
+#include "base/memory/ptr_util.h"
 #include "components/grit/components_resources.h"
 #include "components/sync/driver/about_sync_util.h"
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
@@ -49,7 +50,7 @@
     : web::WebUIIOSController(web_ui) {
   web::WebUIIOSDataSource::Add(ios::ChromeBrowserState::FromWebUIIOS(web_ui),
                                CreateSyncInternalsHTMLSource());
-  web_ui->AddMessageHandler(new SyncInternalsMessageHandler);
+  web_ui->AddMessageHandler(base::MakeUnique<SyncInternalsMessageHandler>());
 }
 
 SyncInternalsUI::~SyncInternalsUI() {}
diff --git a/ios/chrome/browser/ui/webui/version_ui.mm b/ios/chrome/browser/ui/webui/version_ui.mm
index b7dc8c82..76a51fd 100644
--- a/ios/chrome/browser/ui/webui/version_ui.mm
+++ b/ios/chrome/browser/ui/webui/version_ui.mm
@@ -5,6 +5,7 @@
 #include "ios/chrome/browser/ui/webui/version_ui.h"
 
 #include "base/command_line.h"
+#include "base/memory/ptr_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
 #include "build/build_config.h"
@@ -108,7 +109,7 @@
 }  // namespace
 
 VersionUI::VersionUI(web::WebUIIOS* web_ui) : web::WebUIIOSController(web_ui) {
-  web_ui->AddMessageHandler(new VersionHandler());
+  web_ui->AddMessageHandler(base::MakeUnique<VersionHandler>());
   web::WebUIIOSDataSource::Add(ios::ChromeBrowserState::FromWebUIIOS(web_ui),
                                CreateVersionUIDataSource());
 }
diff --git a/ios/chrome/test/ocmock/BUILD.gn b/ios/chrome/test/ocmock/BUILD.gn
index a023247..1b83041 100644
--- a/ios/chrome/test/ocmock/BUILD.gn
+++ b/ios/chrome/test/ocmock/BUILD.gn
@@ -7,8 +7,6 @@
   sources = [
     "OCMockObject+BreakpadControllerTesting.h",
     "OCMockObject+BreakpadControllerTesting.mm",
-    "OCMockObject+CrOCMockAdditions.h",
-    "OCMockObject+CrOCMockAdditions.mm",
     "scoped_mock_object.h",
     "scoped_verifying_mock_object.h",
   ]
diff --git a/ios/chrome/test/ocmock/OCMockObject+CrOCMockAdditions.h b/ios/chrome/test/ocmock/OCMockObject+CrOCMockAdditions.h
deleted file mode 100644
index 53c229e6..0000000
--- a/ios/chrome/test/ocmock/OCMockObject+CrOCMockAdditions.h
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef IOS_CHROME_TEST_OCMOCK_OCMOCKOBJECT_CROCMOCKADDITIONS_H_
-#define IOS_CHROME_TEST_OCMOCK_OCMOCKOBJECT_CROCMOCKADDITIONS_H_
-
-#import "third_party/ocmock/OCMock/OCMock.h"
-
-@interface OCMockObject (CrOCMockAdditions)
-
-- (BOOL)isStubbed:(SEL)selector;
-
-- (void)removeStub:(SEL)selector;
-
-@end
-
-#endif  // IOS_CHROME_TEST_OCMOCK_OCMOCKOBJECT_CROCMOCKADDITIONS_H_
diff --git a/ios/chrome/test/ocmock/OCMockObject+CrOCMockAdditions.mm b/ios/chrome/test/ocmock/OCMockObject+CrOCMockAdditions.mm
deleted file mode 100644
index 5ddea6d..0000000
--- a/ios/chrome/test/ocmock/OCMockObject+CrOCMockAdditions.mm
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#import "ios/chrome/test/ocmock/OCMockObject+CrOCMockAdditions.h"
-
-@implementation OCMockObject (CrOCMockAdditions)
-
-- (BOOL)isStubbed:(SEL)selector {
-  for (OCMockRecorder* recorder in recorders) {
-    NSMethodSignature* signature = [self methodSignatureForSelector:selector];
-    NSInvocation* invocation =
-        [NSInvocation invocationWithMethodSignature:signature];
-    [invocation setSelector:selector];
-    if ([recorder matchesInvocation:invocation]) {
-      return YES;
-    }
-  }
-  return NO;
-}
-
-- (void)removeStub:(SEL)selector {
-  OCMockRecorder* stubRecorder = nil;
-  for (OCMockRecorder* recorder in recorders) {
-    NSMethodSignature* signature = [self methodSignatureForSelector:selector];
-    NSInvocation* invocation =
-        [NSInvocation invocationWithMethodSignature:signature];
-    [invocation setSelector:selector];
-    if ([recorder matchesInvocation:invocation]) {
-      stubRecorder = recorder;
-      break;
-    }
-  }
-  if (stubRecorder) {
-    [recorders removeObject:stubRecorder];
-  }
-}
-
-@end
diff --git a/ios/net/cookies/cookie_store_ios.h b/ios/net/cookies/cookie_store_ios.h
index 2870bde..6108ee1 100644
--- a/ios/net/cookies/cookie_store_ios.h
+++ b/ios/net/cookies/cookie_store_ios.h
@@ -136,13 +136,6 @@
 
   bool IsEphemeral() override;
 
-  // Changes the synchronization of the store.
-  // If |synchronized| is true, then the system cookie store is used as a
-  // backend, else |cookie_monster_| is used. Cookies are moved from one to
-  // the other accordingly.
-  // TODO(crbug.com/676144): Remove this method. It is used only in tests.
-  void SetSynchronizedWithSystemStore(bool synchronized);
-
  private:
   CookieStoreIOS(
       net::CookieMonster::PersistentCookieStore* persistent_store,
@@ -167,13 +160,9 @@
   // Returns true if the system cookie store policy is
   // |NSHTTPCookieAcceptPolicyAlways|.
   bool SystemCookiesAllowed();
-  // Converts |cookies| to NSHTTPCookie and add them to the system store.
-  void AddCookiesToSystemStore(const net::CookieList& cookies);
   // Copies the cookies to the backing CookieMonster. If the cookie store is not
   // synchronized with the system store, this is a no-op.
   void WriteToCookieMonster(NSArray* system_cookies);
-  // Runs all the pending tasks.
-  void RunAllPendingTasks();
 
   // Inherited CookieNotificationObserver methods.
   void OnSystemCookiesChanged() override;
diff --git a/ios/net/cookies/cookie_store_ios.mm b/ios/net/cookies/cookie_store_ios.mm
index 6da4c386..149d22b 100644
--- a/ios/net/cookies/cookie_store_ios.mm
+++ b/ios/net/cookies/cookie_store_ios.mm
@@ -41,13 +41,6 @@
 
 namespace {
 
-#if !defined(NDEBUG)
-// The current cookie store. This weak pointer must not be used to do actual
-// work. Its only purpose is to check that there is only one synchronized
-// cookie store.
-CookieStoreIOS* g_current_synchronized_store = nullptr;
-#endif
-
 #pragma mark NotificationTrampoline
 
 // NotificationTrampoline dispatches cookie notifications to all the existing
@@ -734,96 +727,12 @@
   creation_time_manager_->Clear();
 }
 
-void CookieStoreIOS::SetSynchronizedWithSystemStore(bool synchronized) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-
-  if (synchronized == (synchronization_state_ != NOT_SYNCHRONIZED))
-    return;  // The cookie store is already in the desired state.
-
-#if !defined(NDEBUG)
-  if (!synchronized) {
-    DCHECK_EQ(this, g_current_synchronized_store)
-        << "This cookie store was not synchronized";
-    g_current_synchronized_store = nullptr;
-  } else {
-    DCHECK_EQ((CookieStoreIOS*)nullptr, g_current_synchronized_store)
-        << "Un-synchronize the current cookie store first.";
-    g_current_synchronized_store = this;
-  }
-#endif
-
-  NSHTTPCookieAcceptPolicy policy =
-      [system_store_ cookieAcceptPolicy];
-  DCHECK(policy == NSHTTPCookieAcceptPolicyAlways ||
-         policy == NSHTTPCookieAcceptPolicyNever);
-
-  // If cookies are disabled, the system cookie store should be empty.
-  DCHECK(policy == NSHTTPCookieAcceptPolicyAlways ||
-         ![[system_store_ cookies] count]);
-
-  // If cookies are disabled, nothing is done now, the work will be done when
-  // cookies are re-enabled.
-  if (policy == NSHTTPCookieAcceptPolicyAlways) {
-    if (synchronized) {
-      synchronization_state_ = SYNCHRONIZING;
-      ClearSystemStore();
-      cookie_monster_->GetAllCookiesAsync(
-          base::Bind(&CookieStoreIOS::AddCookiesToSystemStore,
-                     weak_factory_.GetWeakPtr()));
-      return;
-    } else {
-      // Copy the cookies from the global store to |cookie_monster_|.
-      FlushStore(base::Closure());
-    }
-  }
-  synchronization_state_ = synchronized ? SYNCHRONIZED : NOT_SYNCHRONIZED;
-
-  if (synchronization_state_ == NOT_SYNCHRONIZED) {
-    // If there are pending tasks, then it means that the synchronization is
-    // being canceled. All pending tasks can be sent to cookie_monster_.
-    RunAllPendingTasks();
-  }
-}
-
 bool CookieStoreIOS::SystemCookiesAllowed() {
   DCHECK(thread_checker_.CalledOnValidThread());
   return [system_store_ cookieAcceptPolicy] ==
          NSHTTPCookieAcceptPolicyAlways;
 }
 
-void CookieStoreIOS::AddCookiesToSystemStore(const net::CookieList& cookies) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  if (!SystemCookiesAllowed() || synchronization_state_ != SYNCHRONIZING) {
-    // If synchronization was aborted, the pending tasks have been processed at
-    // that time. Now is too late.
-    DCHECK(tasks_pending_synchronization_.empty());
-    return;
-  }
-
-  // Report metrics.
-  if (metrics_enabled_) {
-    size_t cookie_count = cookies.size();
-    UMA_HISTOGRAM_COUNTS_10000("CookieIOS.CookieReadCount", cookie_count);
-    CheckForCookieLoss(cookie_count, COOKIES_READ);
-  }
-
-  net::CookieList::const_iterator it;
-  for (it = cookies.begin(); it != cookies.end(); ++it) {
-    const net::CanonicalCookie& net_cookie = *it;
-    NSHTTPCookie* system_cookie = SystemCookieFromCanonicalCookie(net_cookie);
-    // Canonical cookie may not be convertable into system cookie if it contains
-    // invalid characters.
-    if (!system_cookie)
-      continue;
-    [system_store_ setCookie:system_cookie];
-    creation_time_manager_->SetCreationTime(system_cookie,
-                                            net_cookie.CreationDate());
-  }
-
-  synchronization_state_ = SYNCHRONIZED;
-  RunAllPendingTasks();
-}
-
 void CookieStoreIOS::WriteToCookieMonster(NSArray* system_cookies) {
   DCHECK(thread_checker_.CalledOnValidThread());
   if (synchronization_state_ != SYNCHRONIZED)
@@ -845,17 +754,6 @@
     UMA_HISTOGRAM_COUNTS_10000("CookieIOS.CookieWrittenCount", cookie_count);
 }
 
-void CookieStoreIOS::RunAllPendingTasks() {
-  // Executing the tasks while synchronizing would not run the tasks, but merely
-  // re-enqueue them. This function also does not support mutation of the queue
-  // during the iteration.
-  DCHECK(synchronization_state_ != SYNCHRONIZING);
-  for (const auto& task : tasks_pending_synchronization_) {
-    task.Run();
-  }
-  tasks_pending_synchronization_.clear();
-}
-
 void CookieStoreIOS::DeleteCookiesWithFilter(const CookieFilterFunction& filter,
                                              const DeleteCallback& callback) {
   DCHECK(thread_checker_.CalledOnValidThread());
diff --git a/ios/public/provider/chrome/browser/BUILD.gn b/ios/public/provider/chrome/browser/BUILD.gn
index 5004fb1..d28965c5 100644
--- a/ios/public/provider/chrome/browser/BUILD.gn
+++ b/ios/public/provider/chrome/browser/BUILD.gn
@@ -43,17 +43,4 @@
     "//ios/public/provider/chrome/browser/voice:test_support",
     "//testing/gtest",
   ]
-
-  # TODO(sdefresne): remove once downstream has been converted to depends
-  # directly on the sub-targets.
-  public_deps = [
-    "//ios/public/provider/chrome/browser/distribution:test_support",
-    "//ios/public/provider/chrome/browser/images:test_support",
-    "//ios/public/provider/chrome/browser/native_app_launcher:test_support",
-    "//ios/public/provider/chrome/browser/omaha:test_support",
-    "//ios/public/provider/chrome/browser/signin:test_support",
-    "//ios/public/provider/chrome/browser/ui:test_support",
-    "//ios/public/provider/chrome/browser/user_feedback:test_support",
-    "//ios/public/provider/chrome/browser/voice:test_support",
-  ]
 }
diff --git a/ios/public/provider/chrome/browser/build_config.gni b/ios/public/provider/chrome/browser/build_config.gni
index 676dd82..aaf2ee9 100644
--- a/ios/public/provider/chrome/browser/build_config.gni
+++ b/ios/public/provider/chrome/browser/build_config.gni
@@ -20,5 +20,5 @@
 
   # Label of the target providing implementation for ChromeBrowserProvider.
   # Overridden when using the Google-internal repository to build Chrome on iOS.
-  ios_provider_target = "//ios/chrome/browser:downstream_provider_factory"
+  ios_provider_target = "//ios/chrome/browser/providers:provider_factory"
 }
diff --git a/ios/web/net/request_tracker_impl.h b/ios/web/net/request_tracker_impl.h
index f9fbdba..e1695a6 100644
--- a/ios/web/net/request_tracker_impl.h
+++ b/ios/web/net/request_tracker_impl.h
@@ -7,13 +7,15 @@
 
 #import <Foundation/Foundation.h>
 #include <stdint.h>
+
 #include <map>
+#include <memory>
 #include <set>
+#include <vector>
 
 #include "base/callback_forward.h"
 #import "base/mac/scoped_nsobject.h"
 #include "base/memory/ref_counted.h"
-#include "base/memory/scoped_vector.h"
 #include "base/memory/weak_ptr.h"
 #import "ios/net/request_tracker.h"
 #import "ios/web/net/crw_request_tracker_delegate.h"
@@ -344,7 +346,7 @@
   // All the live requests associated with the tracker.
   std::set<net::URLRequest*> live_requests_;
   // A list of all the TrackerCounts, including the finished ones.
-  ScopedVector<TrackerCounts> counts_;
+  std::vector<std::unique_ptr<TrackerCounts>> counts_;
   // The system shall never allow the page load estimate to go back.
   float previous_estimate_;
   // Index of the first request to consider for building the estimation.
diff --git a/ios/web/net/request_tracker_impl.mm b/ios/web/net/request_tracker_impl.mm
index 5a6014f..bc0986f9 100644
--- a/ios/web/net/request_tracker_impl.mm
+++ b/ios/web/net/request_tracker_impl.mm
@@ -15,6 +15,7 @@
 #import "base/mac/bind_objc_block.h"
 #import "base/mac/scoped_nsobject.h"
 #include "base/macros.h"
+#include "base/memory/ptr_util.h"
 #include "base/strings/string_util.h"
 #include "base/strings/sys_string_conversions.h"
 #include "base/synchronization/lock.h"
@@ -487,10 +488,10 @@
     new_estimate_round_ = false;
   }
   const GURL& url = request->original_url();
-  TrackerCounts* counts = new TrackerCounts(
-      GURLByRemovingRefFromGURL(url), request);
-  counts_.push_back(counts);
-  counts_by_request_[request] = counts;
+  auto counts =
+      base::MakeUnique<TrackerCounts>(GURLByRemovingRefFromGURL(url), request);
+  counts_by_request_[request] = counts.get();
+  counts_.push_back(std::move(counts));
   if (page_url_.SchemeIsCryptographic() && !url.SchemeIsCryptographic())
     has_mixed_content_ = true;
   Notify();
@@ -787,17 +788,17 @@
     return;
 
   const GURL page_origin = page_url_.GetOrigin();
-  ScopedVector<TrackerCounts>::iterator it;
-  for (it = counts_.begin(); it != counts_.end(); ++it) {
-    if (!(*it)->ssl_info.is_valid())
+  for (const auto& tracker_count : counts_) {
+    if (!tracker_count->ssl_info.is_valid())
       continue;  // No SSL info at this point in time on this tracker.
 
-    GURL request_origin = (*it)->url.GetOrigin();
+    GURL request_origin = tracker_count->url.GetOrigin();
     if (request_origin != page_origin)
       continue;  // Not interesting in the context of the page.
 
-    base::scoped_nsobject<CRWSSLCarrier> carrier(
-        [[CRWSSLCarrier alloc] initWithTracker:this counts:*it]);
+    base::scoped_nsobject<CRWSSLCarrier> carrier([[CRWSSLCarrier alloc]
+        initWithTracker:this
+                 counts:tracker_count.get()]);
     web::WebThread::PostTask(
         web::WebThread::UI, FROM_HERE,
         base::Bind(&RequestTrackerImpl::NotifyUpdatedSSLStatus, this, carrier));
@@ -927,26 +928,25 @@
   if (is_closing_)
     return;
 
-  ScopedVector<TrackerCounts>::iterator it;
-  for (it = counts_.begin(); it != counts_.end(); ++it) {
+  for (const auto& tracker_count : counts_) {
     // Check if the value hasn't changed via a user action.
-    if ((*it)->ssl_judgment == CertPolicy::UNKNOWN)
-      EvaluateSSLCallbackForCounts(*it);
+    if (tracker_count->ssl_judgment == CertPolicy::UNKNOWN)
+      EvaluateSSLCallbackForCounts(tracker_count.get());
 
-    CertPolicy::Judgment judgment = (*it)->ssl_judgment;
+    CertPolicy::Judgment judgment = tracker_count->ssl_judgment;
     if (judgment == CertPolicy::ALLOWED)
       continue;
 
     // SSL errors on subrequests are simply ignored. The call to
     // EvaluateSSLCallbackForCounts() cancelled the request and nothing will
     // restart it.
-    if ((*it)->is_subrequest)
+    if (tracker_count->is_subrequest)
       continue;
 
     if (!current_ssl_error_) {
       // For the UNKNOWN and DENIED state the information should be pushed to
       // the delegate. But only one at a time.
-      current_ssl_error_ = (*it);
+      current_ssl_error_ = tracker_count.get();
       base::scoped_nsobject<CRWSSLCarrier> carrier([[CRWSSLCarrier alloc]
           initWithTracker:this counts:current_ssl_error_]);
       web::WebThread::PostTask(
@@ -972,11 +972,9 @@
 
   PageCounts page_counts;
 
-  ScopedVector<TrackerCounts>::iterator it;
-  for (it = counts_.begin() + estimate_start_index_;
-       it != counts_.end(); ++it) {
-    if ((*it)->done) {
-      uint64_t size = (*it)->processed;
+  for (const auto& tracker_count : counts_) {
+    if (tracker_count->done) {
+      uint64_t size = tracker_count->processed;
       page_counts.finished += 1;
       page_counts.finished_bytes += size;
       if (page_counts.largest_byte_size_known < size) {
@@ -984,16 +982,17 @@
       }
     } else {
       page_counts.unfinished += 1;
-      if ((*it)->expected_length) {
-        uint64_t size = (*it)->expected_length;
-        page_counts.unfinished_estimate_bytes_done += (*it)->processed;
+      if (tracker_count->expected_length) {
+        uint64_t size = tracker_count->expected_length;
+        page_counts.unfinished_estimate_bytes_done += tracker_count->processed;
         page_counts.unfinished_estimated_bytes_left += size;
         if (page_counts.largest_byte_size_known < size) {
           page_counts.largest_byte_size_known = size;
         }
       } else {
         page_counts.unfinished_no_estimate += 1;
-        page_counts.unfinished_no_estimate_bytes_done += (*it)->processed;
+        page_counts.unfinished_no_estimate_bytes_done +=
+            tracker_count->processed;
       }
     }
   }
@@ -1081,8 +1080,8 @@
   if (page_url_.SchemeIsCryptographic() && has_mixed_content_) {
     bool old_url_has_mixed_content = false;
     const GURL origin = page_url_.GetOrigin();
-    ScopedVector<TrackerCounts>::iterator it = counts_.begin();
-    while (it != counts_.end() && *it != split_position) {
+    auto it = counts_.begin();
+    while (it != counts_.end() && it->get() != split_position) {
       if (!(*it)->url.SchemeIsCryptographic() &&
           origin == (*it)->first_party_for_cookies_origin) {
         old_url_has_mixed_content = true;
@@ -1110,9 +1109,8 @@
       web::WebThread::UI, FROM_HERE,
       base::Bind(&RequestTrackerImpl::NotifyClearCertificates, this));
   // Report judgements for the new URL.
-  ScopedVector<TrackerCounts>::const_reverse_iterator it;
-  for (it = counts_.rbegin(); it != counts_.rend(); ++it) {
-    TrackerCounts* counts = *it;
+  for (auto it = counts_.rbegin(); it != counts_.rend(); ++it) {
+    TrackerCounts* counts = it->get();
     if (counts->allowed_by_user) {
       std::string host = counts->url.host();
       web::WebThread::PostTask(
@@ -1144,7 +1142,7 @@
   // Locate the request with this url, if present.
   bool new_url_has_mixed_content = false;
   bool url_scheme_is_secure = url.SchemeIsCryptographic();
-  ScopedVector<TrackerCounts>::const_reverse_iterator rit = counts_.rbegin();
+  auto rit = counts_.rbegin();
   while (rit != counts_.rend() && (*rit)->url != url) {
     if (url_scheme_is_secure && !(*rit)->url.SchemeIsCryptographic() &&
         (*rit)->first_party_for_cookies_origin == url.GetOrigin()) {
@@ -1156,7 +1154,7 @@
   // |split_position| will be set to the count for the passed url if it exists.
   TrackerCounts* split_position = NULL;
   if (rit != counts_.rend()) {
-    split_position = (*rit);
+    split_position = rit->get();
   } else {
     // The URL was not found, everything will be trimmed. The mixed content
     // calculation is invalid.
@@ -1169,7 +1167,7 @@
     // domain as the page itself this will allow retrieval of the SSL
     // information.
     if (url_scheme_is_secure && counts_.size()) {
-      TrackerCounts* back = counts_.back();
+      TrackerCounts* back = counts_.back().get();
       const GURL& back_url = back->url;
       if (back_url.SchemeIsCryptographic() &&
           back_url.GetOrigin() == url.GetOrigin() && !back->is_subrequest) {
@@ -1181,13 +1179,13 @@
   RecomputeCertificatePolicy(split_position);
 
   // Trim up to that element.
-  ScopedVector<TrackerCounts>::iterator it = counts_.begin();
-  while (it != counts_.end() && *it != split_position) {
+  auto it = counts_.begin();
+  while (it != counts_.end() && it->get() != split_position) {
     if (!(*it)->done) {
       // This is for an unfinished request on a previous page. We do not care
       // about those anymore. Cancel the request.
       if ((*it)->ssl_judgment == CertPolicy::UNKNOWN)
-        CancelRequestForCounts(*it);
+        CancelRequestForCounts(it->get());
       counts_by_request_.erase((*it)->request);
     }
     it = counts_.erase(it);
@@ -1233,9 +1231,8 @@
   DCHECK_CURRENTLY_ON(web::WebThread::IO);
 
   NSMutableArray* urls = [NSMutableArray array];
-  ScopedVector<TrackerCounts>::iterator it;
-  for (it = counts_.begin(); it != counts_.end(); ++it)
-    [urls addObject:(*it)->Description()];
+  for (const auto& tracker_count : counts_)
+    [urls addObject:tracker_count->Description()];
 
   return [NSString stringWithFormat:@"RequestGroupID %@\n%@\n%@",
                                     request_group_id_.get(),
diff --git a/ios/web/net/request_tracker_impl_unittest.mm b/ios/web/net/request_tracker_impl_unittest.mm
index b88873cb..0875087 100644
--- a/ios/web/net/request_tracker_impl_unittest.mm
+++ b/ios/web/net/request_tracker_impl_unittest.mm
@@ -6,11 +6,13 @@
 
 #include <stddef.h>
 
+#include <memory>
+#include <vector>
+
 #include "base/logging.h"
 #import "base/mac/scoped_nsobject.h"
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
-#include "base/memory/scoped_vector.h"
 #include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
 #include "base/strings/sys_string_conversions.h"
@@ -172,8 +174,8 @@
   scoped_refptr<web::RequestTrackerImpl> tracker_;
   base::scoped_nsobject<NSString> request_group_id_;
   web::TestBrowserState browser_state_;
-  ScopedVector<net::URLRequestContext> contexts_;
-  ScopedVector<net::URLRequest> requests_;
+  std::vector<std::unique_ptr<net::URLRequestContext>> contexts_;
+  std::vector<std::unique_ptr<net::URLRequest>> requests_;
   net::URLRequestJobFactoryImpl job_factory_;
 
   GURL GetURL(size_t i) {
@@ -254,11 +256,9 @@
       url = GetURL(requests_.size());
 
     while (i >= requests_.size()) {
-      contexts_.push_back(new net::URLRequestContext());
-      requests_.push_back(
-          contexts_[i]
-              ->CreateRequest(url, net::DEFAULT_PRIORITY, &request_delegate_)
-              .release());
+      contexts_.push_back(base::MakeUnique<net::URLRequestContext>());
+      requests_.push_back(contexts_[i]->CreateRequest(
+          url, net::DEFAULT_PRIORITY, &request_delegate_));
 
       if (secure) {
         // Put a valid SSLInfo inside
@@ -274,7 +274,7 @@
       }
     }
     EXPECT_TRUE(!secure == !requests_[i]->url().SchemeIsCryptographic());
-    return requests_[i];
+    return requests_[i].get();
   }
 
   DummyURLRequestDelegate request_delegate_;
diff --git a/ios/web/public/web_state/ui/crw_web_delegate.h b/ios/web/public/web_state/ui/crw_web_delegate.h
index 7a51db7..2dc7fed 100644
--- a/ios/web/public/web_state/ui/crw_web_delegate.h
+++ b/ios/web/public/web_state/ui/crw_web_delegate.h
@@ -50,8 +50,6 @@
 // Called when the page calls window.close() on itself. Begin the shut-down
 // sequence for this controller.
 - (void)webPageOrderedClose;
-// Opens a URL with the given parameters.
-- (void)openURLWithParams:(const web::WebState::OpenURLParams&)params;
 // Called when an external app needs to be opened, it also passes |linkClicked|
 // to track if this call was a result of user action or not. Returns YES iff
 // |URL| is launched in an external app.
diff --git a/ios/web/public/web_state/web_state_delegate.h b/ios/web/public/web_state/web_state_delegate.h
index 358bed7..2392d11 100644
--- a/ios/web/public/web_state/web_state_delegate.h
+++ b/ios/web/public/web_state/web_state_delegate.h
@@ -8,12 +8,12 @@
 #include <set>
 
 #include "base/callback.h"
+#import "ios/web/public/web_state/web_state.h"
 
 namespace web {
 
 struct ContextMenuParams;
 class JavaScriptDialogPresenter;
-class WebState;
 
 // Objects implement this interface to get notified about changes in the
 // WebState and to provide necessary functionality.
@@ -21,6 +21,11 @@
  public:
   WebStateDelegate();
 
+  // Returns the WebState the URL is opened in, or nullptr if the URL wasn't
+  // opened immediately.
+  virtual WebState* OpenURLFromWebState(WebState*,
+                                        const WebState::OpenURLParams&);
+
   // Notifies the delegate that the page has made some progress loading.
   // |progress| is a value between 0.0 (nothing loaded) to 1.0 (page fully
   // loaded).
diff --git a/ios/web/public/web_state/web_state_delegate_bridge.h b/ios/web/public/web_state/web_state_delegate_bridge.h
index 3826edf..8378da6 100644
--- a/ios/web/public/web_state/web_state_delegate_bridge.h
+++ b/ios/web/public/web_state/web_state_delegate_bridge.h
@@ -14,6 +14,11 @@
 @protocol CRWWebStateDelegate<NSObject>
 @optional
 
+// Returns the WebState the URL is opened in, or nullptr if the URL wasn't
+// opened immediately.
+- (web::WebState*)webState:(web::WebState*)webState
+         openURLWithParams:(const web::WebState::OpenURLParams&)params;
+
 // Called when the page has made some progress loading. |progress| is a value
 // between 0.0 (nothing loaded) to 1.0 (page fully loaded).
 - (void)webState:(web::WebState*)webState didChangeProgress:(double)progress;
@@ -41,6 +46,8 @@
   ~WebStateDelegateBridge() override;
 
   // web::WebStateDelegate methods.
+  WebState* OpenURLFromWebState(WebState*,
+                                const WebState::OpenURLParams&) override;
   void LoadProgressChanged(WebState* source, double progress) override;
   bool HandleContextMenu(WebState* source,
                          const ContextMenuParams& params) override;
diff --git a/ios/web/public/web_state/web_state_observer_bridge.h b/ios/web/public/web_state/web_state_observer_bridge.h
index f230d93..81e6947 100644
--- a/ios/web/public/web_state/web_state_observer_bridge.h
+++ b/ios/web/public/web_state/web_state_observer_bridge.h
@@ -30,7 +30,7 @@
         (const web::LoadCommittedDetails&)load_details;
 
 // Invoked by WebStateObserverBridge::PageLoaded.
-- (void)webStateDidLoadPage:(web::WebState*)webState;
+- (void)webStateDidLoadPage:(web::WebState*)webState withSuccess:(BOOL)success;
 
 // Invoked by WebStateObserverBridge::InterstitialDismissed.
 - (void)webStateDidDismissInterstitial:(web::WebState*)webState;
diff --git a/ios/web/public/webui/web_ui_ios.h b/ios/web/public/webui/web_ui_ios.h
index 0da4be8..605348d 100644
--- a/ios/web/public/webui/web_ui_ios.h
+++ b/ios/web/public/webui/web_ui_ios.h
@@ -41,7 +41,8 @@
   virtual void SetController(WebUIIOSController* controller) = 0;
 
   // Takes ownership of |handler|, which will be destroyed when the WebUIIOS is.
-  virtual void AddMessageHandler(WebUIIOSMessageHandler* handler) = 0;
+  virtual void AddMessageHandler(
+      std::unique_ptr<WebUIIOSMessageHandler> handler) = 0;
 
   // Used by WebUIIOSMessageHandlers. If the given message is already
   // registered, the call has no effect unless |register_callback_overwrites_|
diff --git a/ios/web/shell/view_controller.mm b/ios/web/shell/view_controller.mm
index 8b33ba70..97a43bc7 100644
--- a/ios/web/shell/view_controller.mm
+++ b/ios/web/shell/view_controller.mm
@@ -280,7 +280,7 @@
   [self updateToolbar];
 }
 
-- (void)webStateDidLoadPage:(web::WebState*)webState {
+- (void)webStateDidLoadPage:(web::WebState*)webState withSuccess:(BOOL)success {
   DCHECK_EQ(_webState.get(), webState);
   [self updateToolbar];
 }
diff --git a/ios/web/web_state/ui/crw_web_controller.mm b/ios/web/web_state/ui/crw_web_controller.mm
index df53e2a..038c51f 100644
--- a/ios/web/web_state/ui/crw_web_controller.mm
+++ b/ios/web/web_state/ui/crw_web_controller.mm
@@ -12,6 +12,7 @@
 #include <cmath>
 #include <memory>
 #include <utility>
+#include <vector>
 
 #include "base/callback.h"
 #include "base/containers/mru_cache.h"
@@ -27,6 +28,7 @@
 #import "base/mac/objc_property_releaser.h"
 #include "base/mac/scoped_cftyperef.h"
 #import "base/mac/scoped_nsobject.h"
+#include "base/memory/ptr_util.h"
 #include "base/metrics/histogram.h"
 #include "base/metrics/user_metrics.h"
 #include "base/metrics/user_metrics_action.h"
@@ -173,10 +175,6 @@
 // Key of UMA IOSFix.ViewportZoomBugCount histogram.
 const char kUMAViewportZoomBugCount[] = "Renderer.ViewportZoomBugCount";
 
-// A tag for the web view, so that tests can identify it. This is used instead
-// of exposing a getter (and deliberately not exposed in the header) to make it
-// *very* clear that this is a hack which should only be used as a last resort.
-const NSUInteger kWebViewTag = 0x3eb71e3;
 // URL scheme for messages sent from javascript for asynchronous processing.
 NSString* const kScriptMessageName = @"crwebinvoke";
 
@@ -319,7 +317,8 @@
   // WebControllerObserverBridge in order to listen from WebState callbacks.
   // TODO(droger): Remove |_observerBridges| when all CRWWebControllerObservers
   // are converted to WebStateObservers.
-  ScopedVector<web::WebControllerObserverBridge> _observerBridges;
+  std::vector<std::unique_ptr<web::WebControllerObserverBridge>>
+      _observerBridges;
   // YES if a user interaction has been registered at any time once the page has
   // loaded.
   BOOL _userInteractionRegistered;
@@ -4664,7 +4663,6 @@
 
     DCHECK(_webView);
 
-    [_webView setTag:kWebViewTag];
     [_webView setAutoresizingMask:UIViewAutoresizingFlexibleWidth |
                                   UIViewAutoresizingFlexibleHeight];
     [_webView setBackgroundColor:[UIColor colorWithWhite:0.2 alpha:1.0]];
@@ -5723,8 +5721,8 @@
   }
   DCHECK(![_observers containsObject:observer]);
   [_observers addObject:observer];
-  _observerBridges.push_back(
-      new web::WebControllerObserverBridge(observer, self.webStateImpl, self));
+  _observerBridges.push_back(base::MakeUnique<web::WebControllerObserverBridge>(
+      observer, self.webStateImpl, self));
 
   if ([observer respondsToSelector:@selector(setWebViewProxy:controller:)])
     [observer setWebViewProxy:_webViewProxy controller:self];
@@ -5734,10 +5732,12 @@
   DCHECK([_observers containsObject:observer]);
   [_observers removeObject:observer];
   // Remove the associated WebControllerObserverBridge.
-  auto it = std::find_if(_observerBridges.begin(), _observerBridges.end(),
-                         [observer](web::WebControllerObserverBridge* bridge) {
-                           return bridge->web_controller_observer() == observer;
-                         });
+  auto it = std::find_if(
+      _observerBridges.begin(), _observerBridges.end(),
+      [observer](
+          const std::unique_ptr<web::WebControllerObserverBridge>& bridge) {
+        return bridge->web_controller_observer() == observer;
+      });
   DCHECK(it != _observerBridges.end());
   _observerBridges.erase(it);
 }
diff --git a/ios/web/web_state/web_state_delegate.mm b/ios/web/web_state/web_state_delegate.mm
index 1233533..68e6fcd9 100644
--- a/ios/web/web_state/web_state_delegate.mm
+++ b/ios/web/web_state/web_state_delegate.mm
@@ -18,6 +18,12 @@
   DCHECK(attached_states_.empty());
 }
 
+WebState* WebStateDelegate::OpenURLFromWebState(
+    WebState*,
+    const WebState::OpenURLParams&) {
+  return nullptr;
+}
+
 void WebStateDelegate::LoadProgressChanged(WebState*, double) {}
 
 bool WebStateDelegate::HandleContextMenu(WebState*, const ContextMenuParams&) {
diff --git a/ios/web/web_state/web_state_delegate_bridge.mm b/ios/web/web_state/web_state_delegate_bridge.mm
index a82c34c..bd1dfca4 100644
--- a/ios/web/web_state/web_state_delegate_bridge.mm
+++ b/ios/web/web_state/web_state_delegate_bridge.mm
@@ -14,6 +14,14 @@
 
 WebStateDelegateBridge::~WebStateDelegateBridge() {}
 
+WebState* WebStateDelegateBridge::OpenURLFromWebState(
+    WebState* source,
+    const WebState::OpenURLParams& params) {
+  if ([delegate_ respondsToSelector:@selector(webState:openURLWithParams:)])
+    return [delegate_ webState:source openURLWithParams:params];
+  return nullptr;
+}
+
 void WebStateDelegateBridge::LoadProgressChanged(WebState* source,
                                                  double progress) {
   if ([delegate_ respondsToSelector:@selector(webState:didChangeProgress:)])
diff --git a/ios/web/web_state/web_state_delegate_bridge_unittest.mm b/ios/web/web_state/web_state_delegate_bridge_unittest.mm
index fa1754d..9d882e20e 100644
--- a/ios/web/web_state/web_state_delegate_bridge_unittest.mm
+++ b/ios/web/web_state/web_state_delegate_bridge_unittest.mm
@@ -8,10 +8,12 @@
 
 #import "base/mac/scoped_nsobject.h"
 #include "base/strings/utf_string_conversions.h"
+#import "ios/web/public/test/fakes/test_web_state.h"
 #import "ios/web/public/web_state/context_menu_params.h"
 #import "ios/web/web_state/web_state_delegate_stub.h"
 #include "testing/platform_test.h"
 #import "third_party/ocmock/gtest_support.h"
+#include "ui/base/page_transition_types.h"
 
 namespace web {
 
@@ -36,8 +38,33 @@
 
   base::scoped_nsprotocol<id> delegate_;
   std::unique_ptr<WebStateDelegateBridge> bridge_;
+  web::TestWebState test_web_state_;
 };
 
+// Tests |webState:openURLWithParams:| forwarding.
+TEST_F(WebStateDelegateBridgeTest, OpenURLFromWebState) {
+  ASSERT_FALSE([delegate_ webState]);
+  ASSERT_FALSE([delegate_ openURLParams]);
+
+  web::WebState::OpenURLParams params(
+      GURL("https://chromium.test/"),
+      web::Referrer(GURL("https://chromium2.test/"), ReferrerPolicyNever),
+      WindowOpenDisposition::NEW_WINDOW, ui::PAGE_TRANSITION_FORM_SUBMIT, true);
+  EXPECT_EQ(&test_web_state_,
+            bridge_->OpenURLFromWebState(&test_web_state_, params));
+
+  EXPECT_EQ(&test_web_state_, [delegate_ webState]);
+  const web::WebState::OpenURLParams* result_params = [delegate_ openURLParams];
+  ASSERT_TRUE(result_params);
+  EXPECT_EQ(params.url, result_params->url);
+  EXPECT_EQ(params.referrer.url, result_params->referrer.url);
+  EXPECT_EQ(params.referrer.policy, result_params->referrer.policy);
+  EXPECT_EQ(params.disposition, result_params->disposition);
+  EXPECT_EQ(static_cast<int>(params.transition),
+            static_cast<int>(result_params->transition));
+  EXPECT_EQ(params.is_renderer_initiated, result_params->is_renderer_initiated);
+}
+
 // Tests |LoadProgressChanged| forwarding.
 TEST_F(WebStateDelegateBridgeTest, LoadProgressChanged) {
   ASSERT_EQ(0.0, [delegate_ changedProgress]);
diff --git a/ios/web/web_state/web_state_delegate_stub.h b/ios/web/web_state/web_state_delegate_stub.h
index 7398dca..262ccc0 100644
--- a/ios/web/web_state/web_state_delegate_stub.h
+++ b/ios/web/web_state/web_state_delegate_stub.h
@@ -11,7 +11,10 @@
 // Stub implementation for CRWWebStateDelegate protocol.
 @interface CRWWebStateDelegateStub
     : OCMockComplexTypeHelper<CRWWebStateDelegate>
-// web::WebState received in delegate method calls..
+// web::WebState::OpenURLParams in |webState:openURLWithParams:| call.
+@property(nonatomic, readonly)
+    const web::WebState::OpenURLParams* openURLParams;
+// web::WebState received in delegate method calls.
 @property(nonatomic, readonly) web::WebState* webState;
 // Progress received in |webState:didChangeProgress| call.
 @property(nonatomic, readonly) double changedProgress;
diff --git a/ios/web/web_state/web_state_delegate_stub.mm b/ios/web/web_state/web_state_delegate_stub.mm
index 000d842..740ad03 100644
--- a/ios/web/web_state/web_state_delegate_stub.mm
+++ b/ios/web/web_state/web_state_delegate_stub.mm
@@ -9,6 +9,8 @@
 
 @implementation CRWWebStateDelegateStub {
   // Backs up the property with the same name.
+  std::unique_ptr<web::WebState::OpenURLParams> _openURLParams;
+  // Backs up the property with the same name.
   std::unique_ptr<web::ContextMenuParams> _contextMenuParams;
   // Backs up the property with the same name.
   BOOL _javaScriptDialogPresenterRequested;
@@ -17,6 +19,13 @@
 @synthesize webState = _webState;
 @synthesize changedProgress = _changedProgress;
 
+- (web::WebState*)webState:(web::WebState*)webState
+         openURLWithParams:(const web::WebState::OpenURLParams&)params {
+  _webState = webState;
+  _openURLParams.reset(new web::WebState::OpenURLParams(params));
+  return webState;
+}
+
 - (void)webState:(web::WebState*)webState didChangeProgress:(double)progress {
   _webState = webState;
   _changedProgress = progress;
@@ -36,6 +45,10 @@
   return nil;
 }
 
+- (const web::WebState::OpenURLParams*)openURLParams {
+  return _openURLParams.get();
+}
+
 - (web::ContextMenuParams*)contextMenuParams {
   return _contextMenuParams.get();
 }
diff --git a/ios/web/web_state/web_state_impl.mm b/ios/web/web_state/web_state_impl.mm
index 5854cad..4ab5963c 100644
--- a/ios/web/web_state/web_state_impl.mm
+++ b/ios/web/web_state/web_state_impl.mm
@@ -612,7 +612,8 @@
 void WebStateImpl::OpenURL(const WebState::OpenURLParams& params) {
   DCHECK(Configured());
   ClearTransientContentView();
-  [[web_controller_ delegate] openURLWithParams:params];
+  if (delegate_)
+    delegate_->OpenURLFromWebState(this, params);
 }
 
 void WebStateImpl::Stop() {
diff --git a/ios/web/web_state/web_state_observer_bridge.mm b/ios/web/web_state/web_state_observer_bridge.mm
index 4ff34c2d..c92dd93 100644
--- a/ios/web/web_state/web_state_observer_bridge.mm
+++ b/ios/web/web_state/web_state_observer_bridge.mm
@@ -46,9 +46,19 @@
 
 void WebStateObserverBridge::PageLoaded(
     web::PageLoadCompletionStatus load_completion_status) {
-  SEL selector = @selector(webStateDidLoadPage:);
-  if ([observer_ respondsToSelector:selector])
-    [observer_ webStateDidLoadPage:web_state()];
+  SEL selector = @selector(webStateDidLoadPage:withSuccess:);
+  if ([observer_ respondsToSelector:selector]) {
+    BOOL success = NO;
+    switch (load_completion_status) {
+      case PageLoadCompletionStatus::SUCCESS:
+        success = YES;
+        break;
+      case PageLoadCompletionStatus::FAILURE:
+        success = NO;
+        break;
+    }
+    [observer_ webStateDidLoadPage:web_state() withSuccess:success];
+  }
 }
 
 void WebStateObserverBridge::InsterstitialDismissed() {
diff --git a/ios/web/webui/crw_web_ui_manager.mm b/ios/web/webui/crw_web_ui_manager.mm
index 4104f5f..173f5cd 100644
--- a/ios/web/webui/crw_web_ui_manager.mm
+++ b/ios/web/webui/crw_web_ui_manager.mm
@@ -4,11 +4,14 @@
 
 #import "ios/web/webui/crw_web_ui_manager.h"
 
+#include <memory>
+#include <vector>
+
 #include "base/json/string_escape.h"
 #import "base/mac/bind_objc_block.h"
 #import "base/mac/scoped_nsobject.h"
+#include "base/memory/ptr_util.h"
 #include "base/memory/ref_counted_memory.h"
-#include "base/memory/scoped_vector.h"
 #include "base/strings/stringprintf.h"
 #import "base/strings/sys_string_conversions.h"
 #include "base/strings/utf_string_conversions.h"
@@ -69,7 +72,7 @@
 
 @implementation CRWWebUIManager {
   // Set of live WebUI fetchers for retrieving data.
-  ScopedVector<web::URLFetcherBlockAdapter> _fetchers;
+  std::vector<std::unique_ptr<web::URLFetcherBlockAdapter>> _fetchers;
   // Bridge to observe the web state from Objective-C.
   std::unique_ptr<web::WebStateObserverBridge> _webStateObserverBridge;
   // Weak WebStateImpl this CRWWebUIManager is associated with.
@@ -129,7 +132,7 @@
           }];
 }
 
-- (void)webStateDidLoadPage:(web::WebState*)webState {
+- (void)webStateDidLoadPage:(web::WebState*)webState withSuccess:(BOOL)success {
   DCHECK_EQ(webState, _webState);
   // All WebUI pages are HTML based.
   _webState->SetContentsMimeType("text/html");
@@ -293,7 +296,11 @@
 }
 
 - (void)removeFetcher:(web::URLFetcherBlockAdapter*)fetcher {
-  _fetchers.erase(std::find(_fetchers.begin(), _fetchers.end(), fetcher));
+  _fetchers.erase(std::find_if(
+      _fetchers.begin(), _fetchers.end(),
+      [fetcher](const std::unique_ptr<web::URLFetcherBlockAdapter>& ptr) {
+        return ptr.get() == fetcher;
+      }));
 }
 
 #pragma mark - Testing-Only Methods
@@ -301,9 +308,8 @@
 - (std::unique_ptr<web::URLFetcherBlockAdapter>)
     fetcherForURL:(const GURL&)URL
 completionHandler:(web::URLFetcherBlockAdapterCompletion)handler {
-  return std::unique_ptr<web::URLFetcherBlockAdapter>(
-      new web::URLFetcherBlockAdapter(
-          URL, _webState->GetBrowserState()->GetRequestContext(), handler));
+  return base::MakeUnique<web::URLFetcherBlockAdapter>(
+      URL, _webState->GetBrowserState()->GetRequestContext(), handler);
 }
 
 @end
diff --git a/ios/web/webui/web_ui_ios_impl.h b/ios/web/webui/web_ui_ios_impl.h
index ca83b9e..7440cdb 100644
--- a/ios/web/webui/web_ui_ios_impl.h
+++ b/ios/web/webui/web_ui_ios_impl.h
@@ -7,10 +7,10 @@
 
 #include <map>
 #include <memory>
+#include <vector>
 
 #include "base/compiler_specific.h"
 #include "base/macros.h"
-#include "base/memory/scoped_vector.h"
 #include "base/memory/weak_ptr.h"
 #include "ios/web/public/webui/web_ui_ios.h"
 
@@ -30,7 +30,8 @@
   WebState* GetWebState() const override;
   WebUIIOSController* GetController() const override;
   void SetController(WebUIIOSController* controller) override;
-  void AddMessageHandler(WebUIIOSMessageHandler* handler) override;
+  void AddMessageHandler(
+      std::unique_ptr<WebUIIOSMessageHandler> handler) override;
   typedef base::Callback<void(const base::ListValue*)> MessageCallback;
   void RegisterMessageCallback(const std::string& message,
                                const MessageCallback& callback) override;
@@ -65,7 +66,7 @@
   MessageCallbackMap message_callbacks_;
 
   // The WebUIIOSMessageHandlers we own.
-  ScopedVector<WebUIIOSMessageHandler> handlers_;
+  std::vector<std::unique_ptr<WebUIIOSMessageHandler>> handlers_;
 
   // Non-owning pointer to the WebStateImpl this WebUIIOS is associated with.
   WebStateImpl* web_state_;
diff --git a/ios/web/webui/web_ui_ios_impl.mm b/ios/web/webui/web_ui_ios_impl.mm
index 395b4ab0..5822edb7 100644
--- a/ios/web/webui/web_ui_ios_impl.mm
+++ b/ios/web/webui/web_ui_ios_impl.mm
@@ -143,11 +143,12 @@
 // WebUIIOSImpl, protected:
 // -------------------------------------------------------
 
-void WebUIIOSImpl::AddMessageHandler(WebUIIOSMessageHandler* handler) {
+void WebUIIOSImpl::AddMessageHandler(
+    std::unique_ptr<WebUIIOSMessageHandler> handler) {
   DCHECK(!handler->web_ui());
   handler->set_web_ui(this);
   handler->RegisterMessages();
-  handlers_.push_back(handler);
+  handlers_.push_back(std::move(handler));
 }
 
 void WebUIIOSImpl::ExecuteJavascript(const base::string16& javascript) {
diff --git a/media/audio/audio_input_controller.cc b/media/audio/audio_input_controller.cc
index 6bef687..888df2c 100644
--- a/media/audio/audio_input_controller.cc
+++ b/media/audio/audio_input_controller.cc
@@ -351,8 +351,6 @@
     handler_->OnLog(this, "AIC::DoRecord");
 
   stream_->Start(this);
-  if (handler_)
-    handler_->OnRecording(this);
 }
 
 void AudioInputController::DoClose() {
diff --git a/media/audio/audio_input_controller.h b/media/audio/audio_input_controller.h
index e778838..5d4a94a 100644
--- a/media/audio/audio_input_controller.h
+++ b/media/audio/audio_input_controller.h
@@ -59,7 +59,6 @@
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 // Record() ==>                 DoRecord()
 //                      AudioInputStream::Start()
-//                                  .------------------------->  OnRecording()
 //                              kRecording
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 // Close() ==>                  DoClose()
@@ -113,7 +112,6 @@
   class MEDIA_EXPORT EventHandler {
    public:
     virtual void OnCreated(AudioInputController* controller) = 0;
-    virtual void OnRecording(AudioInputController* controller) = 0;
     virtual void OnError(AudioInputController* controller,
                          ErrorCode error_code) = 0;
     virtual void OnData(AudioInputController* controller,
diff --git a/media/audio/audio_input_controller_unittest.cc b/media/audio/audio_input_controller_unittest.cc
index 6b98fb3..6d44002 100644
--- a/media/audio/audio_input_controller_unittest.cc
+++ b/media/audio/audio_input_controller_unittest.cc
@@ -51,7 +51,6 @@
   MockAudioInputControllerEventHandler() {}
 
   MOCK_METHOD1(OnCreated, void(AudioInputController* controller));
-  MOCK_METHOD1(OnRecording, void(AudioInputController* controller));
   MOCK_METHOD2(OnError, void(AudioInputController* controller,
                              AudioInputController::ErrorCode error_code));
   MOCK_METHOD2(OnData,
@@ -120,10 +119,6 @@
   EXPECT_CALL(event_handler, OnCreated(NotNull()))
       .Times(Exactly(1));
 
-  // OnRecording() will be called only once.
-  EXPECT_CALL(event_handler, OnRecording(NotNull()))
-      .Times(Exactly(1));
-
   // OnData() shall be called ten times.
   EXPECT_CALL(event_handler, OnData(NotNull(), NotNull()))
       .Times(AtLeast(10))
@@ -139,7 +134,6 @@
       AudioDeviceDescription::kDefaultDeviceId, NULL);
   ASSERT_TRUE(controller.get());
 
-  // Start recording and trigger one OnRecording() call.
   controller->Record();
 
   // Record and wait until ten OnData() callbacks are received.
@@ -173,13 +167,9 @@
 TEST_F(AudioInputControllerTest, CloseTwice) {
   MockAudioInputControllerEventHandler event_handler;
 
-  // OnRecording() will be called only once.
+  // OnCreated() will be called only once.
   EXPECT_CALL(event_handler, OnCreated(NotNull()));
 
-  // OnRecording() will be called only once.
-  EXPECT_CALL(event_handler, OnRecording(NotNull()))
-      .Times(Exactly(1));
-
   AudioParameters params(AudioParameters::AUDIO_FAKE,
                          kChannelLayout,
                          kSampleRate,
diff --git a/media/audio/audio_input_device.cc b/media/audio/audio_input_device.cc
index 9ebe480..ed5e79d 100644
--- a/media/audio/audio_input_device.cc
+++ b/media/audio/audio_input_device.cc
@@ -155,53 +155,33 @@
   ipc_->RecordStream();
 }
 
-void AudioInputDevice::OnVolume(double volume) {
-  NOTIMPLEMENTED();
-}
-
-void AudioInputDevice::OnStateChanged(
-    AudioInputIPCDelegateState state) {
+void AudioInputDevice::OnError() {
   DCHECK(task_runner()->BelongsToCurrentThread());
 
   // Do nothing if the stream has been closed.
   if (state_ < CREATING_STREAM)
     return;
 
-  // TODO(miu): Clean-up inconsistent and incomplete handling here.
-  // http://crbug.com/180640
-  switch (state) {
-    case AUDIO_INPUT_IPC_DELEGATE_STATE_STOPPED:
-      ShutDownOnIOThread();
-      break;
-    case AUDIO_INPUT_IPC_DELEGATE_STATE_RECORDING:
-      NOTIMPLEMENTED();
-      break;
-    case AUDIO_INPUT_IPC_DELEGATE_STATE_ERROR:
-      DLOG(WARNING) << "AudioInputDevice::OnStateChanged(ERROR)";
-      if (state_ == CREATING_STREAM) {
-        // At this point, we haven't attempted to start the audio thread.
-        // Accessing the hardware might have failed or we may have reached
-        // the limit of the number of allowed concurrent streams.
-        // We must report the error to the |callback_| so that a potential
-        // audio source object will enter the correct state (e.g. 'ended' for
-        // a local audio source).
-        callback_->OnCaptureError(
-            "Maximum allowed input device limit reached or OS failure.");
-      } else {
-        // Don't dereference the callback object if the audio thread
-        // is stopped or stopping.  That could mean that the callback
-        // object has been deleted.
-        // TODO(tommi): Add an explicit contract for clearing the callback
-        // object.  Possibly require calling Initialize again or provide
-        // a callback object via Start() and clear it in Stop().
-        base::AutoLock auto_lock_(audio_thread_lock_);
-        if (audio_thread_)
-          callback_->OnCaptureError("AUDIO_INPUT_IPC_DELEGATE_STATE_ERROR");
-      }
-      break;
-    default:
-      NOTREACHED();
-      break;
+  DLOG(WARNING) << "AudioInputDevice::OnStateChanged(ERROR)";
+  if (state_ == CREATING_STREAM) {
+    // At this point, we haven't attempted to start the audio thread.
+    // Accessing the hardware might have failed or we may have reached
+    // the limit of the number of allowed concurrent streams.
+    // We must report the error to the |callback_| so that a potential
+    // audio source object will enter the correct state (e.g. 'ended' for
+    // a local audio source).
+    callback_->OnCaptureError(
+        "Maximum allowed input device limit reached or OS failure.");
+  } else {
+    // Don't dereference the callback object if the audio thread
+    // is stopped or stopping.  That could mean that the callback
+    // object has been deleted.
+    // TODO(tommi): Add an explicit contract for clearing the callback
+    // object.  Possibly require calling Initialize again or provide
+    // a callback object via Start() and clear it in Stop().
+    base::AutoLock auto_lock_(audio_thread_lock_);
+    if (audio_thread_)
+      callback_->OnCaptureError("IPC delegate state error.");
   }
 }
 
diff --git a/media/audio/audio_input_device.h b/media/audio/audio_input_device.h
index dc6c691..b6244570 100644
--- a/media/audio/audio_input_device.h
+++ b/media/audio/audio_input_device.h
@@ -103,8 +103,7 @@
                        base::SyncSocket::Handle socket_handle,
                        int length,
                        int total_segments) override;
-  void OnVolume(double volume) override;
-  void OnStateChanged(AudioInputIPCDelegateState state) override;
+  void OnError() override;
   void OnIPCClosed() override;
 
  private:
diff --git a/media/audio/audio_input_device_unittest.cc b/media/audio/audio_input_device_unittest.cc
index 046d2eb8..94976a21 100644
--- a/media/audio/audio_input_device_unittest.cc
+++ b/media/audio/audio_input_device_unittest.cc
@@ -64,8 +64,8 @@
       new AudioInputDevice(base::WrapUnique(input_ipc), io_loop.task_runner()));
 }
 
-ACTION_P2(ReportStateChange, device, state) {
-  static_cast<AudioInputIPCDelegate*>(device)->OnStateChanged(state);
+ACTION_P(ReportStateChange, device) {
+  static_cast<AudioInputIPCDelegate*>(device)->OnError();
 }
 
 // Verify that we get an OnCaptureError() callback if CreateStream fails.
@@ -81,8 +81,7 @@
   device->Initialize(params, &callback, 1);
   device->Start();
   EXPECT_CALL(*input_ipc, CreateStream(_, _, _, _, _))
-      .WillOnce(ReportStateChange(device.get(),
-                                  AUDIO_INPUT_IPC_DELEGATE_STATE_ERROR));
+      .WillOnce(ReportStateChange(device.get()));
   EXPECT_CALL(callback, OnCaptureError(_))
       .WillOnce(QuitLoop(io_loop.task_runner()));
   base::RunLoop().Run();
diff --git a/media/audio/audio_input_ipc.h b/media/audio/audio_input_ipc.h
index 203449c0..e69f33d 100644
--- a/media/audio/audio_input_ipc.h
+++ b/media/audio/audio_input_ipc.h
@@ -14,13 +14,6 @@
 
 namespace media {
 
-enum AudioInputIPCDelegateState {
-  AUDIO_INPUT_IPC_DELEGATE_STATE_RECORDING,
-  AUDIO_INPUT_IPC_DELEGATE_STATE_STOPPED,
-  AUDIO_INPUT_IPC_DELEGATE_STATE_ERROR,
-  AUDIO_INPUT_IPC_DELEGATE_STATE_LAST = AUDIO_INPUT_IPC_DELEGATE_STATE_ERROR,
-};
-
 // Contains IPC notifications for the state of the server side
 // (AudioInputController) audio state changes and when an AudioInputController
 // has been created.  Implemented by AudioInputDevice.
@@ -40,10 +33,7 @@
                                int total_segments) = 0;
 
   // Called when state of an audio stream has changed.
-  virtual void OnStateChanged(AudioInputIPCDelegateState state) = 0;
-
-  // Called when the input stream volume has changed.
-  virtual void OnVolume(double volume) = 0;
+  virtual void OnError() = 0;
 
   // Called when the AudioInputIPC object is going away and/or when the
   // IPC channel has been closed and no more IPC requests can be made.
diff --git a/testing/android/docs/components_for_testing.md b/testing/android/docs/components_for_testing.md
new file mode 100644
index 0000000..cb89eae
--- /dev/null
+++ b/testing/android/docs/components_for_testing.md
@@ -0,0 +1,162 @@
+[< Instrumentation](/testing/android/docs/instrumentation.md)
+
+# Creating a component for testing
+
+Creating a component, e.g. a [ContentProvider][1] or [Service][2], for use
+in testing can be tricky. This is particularly true when:
+ - app code and test code are in separate APKs
+ - the test APK instruments the app APK
+ - the test Service depends on app code.
+
+This doc explains the pitfalls in creating a test component and how to
+avoid them.
+
+[TOC]
+
+## What can go wrong with a test component
+
+> **tl;dr:** test components may not be able to access app code when defined in
+> the test APK.
+
+Chromium's instrumentation test suites are all currently set up in the manner
+described above: app code is in one APK (the _APK under test_), test code is
+in another APK (the _test APK_), and auxiliary code, when necessary, is in
+one or more other APKs (_support APKs_). Test APKs build against app code
+but do not retain it in their .dex files. This reduces the size of test APKs
+and avoids potentially conflicting definitions. At instrumentation runtime,
+the test code is loaded into the app package's process, and it's consequently
+able to access code defined in the app APK's .dex file(s). Test components,
+however, run in the test package's process and only have access to code in the
+test APK. While test components referencing app code will build without issue,
+they will fail to link at runtime and will consequently not be able to be
+instantiated.
+
+For example, here's the logcat from an attempt to use a test Service,
+`TestPostMessageService`, that extended an app Service, `PostMessageService`.
+Note that the runtime link failed because the superclass couldn't be resolved,
+and the test Service could not be instantiated as a result.
+
+``` text
+Unable to resolve superclass of Lorg/chromium/chrome/browser/customtabs/TestPostMessageService; (184)
+Link of class 'Lorg/chromium/chrome/browser/customtabs/TestPostMessageService;' failed
+...
+FATAL EXCEPTION: main
+Process: org.chromium.chrome.tests, PID: 30023
+java.lang.RuntimeException:
+    Unable to instantiate service org.chromium.chrome.browser.customtabs.TestPostMessageService:
+        java.lang.ClassNotFoundException:
+        Didn't find class "org.chromium.chrome.browser.customtabs.TestPostMessageService" on path:
+        DexPathList[
+            [zip file "/system/framework/android.test.runner.jar",
+             zip file "/data/app/org.chromium.chrome.tests-1.apk"],
+            nativeLibraryDirectories=[
+                /data/app-lib/org.chromium.chrome.tests-1,
+                /vendor/lib,
+                /system/lib]]
+  at android.app.ActivityThread.handleCreateService(ActivityThread.java:2543)
+  at android.app.ActivityThread.access$1800(ActivityThread.java:135)
+  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
+  at android.os.Handler.dispatchMessage(Handler.java:102)
+  at android.os.Looper.loop(Looper.java:136)
+  at android.app.ActivityThread.main(ActivityThread.java:5001)
+  at java.lang.reflect.Method.invokeNative(Native Method)
+  at java.lang.reflect.Method.invoke(Method.java:515)
+  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
+  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
+  at dalvik.system.NativeStart.main(Native Method)
+Caused by: java.lang.ClassNotFoundException:
+    Didn't find class "org.chromium.chrome.browser.customtabs.TestPostMessageService" on path:
+    DexPathList[
+        [zip file "/system/framework/android.test.runner.jar",
+         zip file "/data/app/org.chromium.chrome.tests-1.apk"],
+        nativeLibraryDirectories=[
+            /data/app-lib/org.chromium.chrome.tests-1,
+            /vendor/lib,
+            /system/lib]]
+  at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
+  at java.lang.ClassLoader.loadClass(ClassLoader.java:497)
+  at java.lang.ClassLoader.loadClass(ClassLoader.java:457)
+  at android.app.ActivityThread.handleCreateService(ActivityThread.java:2540)
+  ... 10 more
+```
+
+## How to implement a test component
+
+There are (at least) two mechanisms for avoiding the failures described above:
+using a support APK or using sharedUserIds.
+
+### Use a support APK
+
+Putting the Service in a support APK lets the build system include all necessary
+code in the .dex without fear of conflicting definitions, as nothing in the
+support APK runs in the same package or process as the test or app code.
+
+To do this:
+
+**Create the component.**
+
+It should either be in an existing directory used by code in the appropriate
+support APK or a new directory for such purpose. In particular, it should be
+in neither a directory containing app code nor a directory containing test
+code.
+
+``` java
+package org.chromium.chrome.test;
+
+import org.chromium.chrome.MyAppService;
+
+public class MyTestService extends MyAppService {
+    ...
+}
+```
+
+**Put the component in a separate gn target.**
+
+This can either be a target upon which the support APK already depends or a new
+target.
+
+``` python
+android_library("my_test_service") {
+  java_files = [ "src/org/chromium/chrome/test/MyTestService.java" ]
+  deps = [ ... ]
+}
+```
+
+The support APK must depend on this target. The target containing your test
+code can also depend on this target if you want to refer to the component
+class directly, e.g., when binding a Service.
+
+> **NOTE:** Even if your test code directly depends on the service target,
+> you won't be able to directly reference the test component instance from
+> test code. Checking a test component's internal state will require adding
+> APIs specifically for that purpose.
+
+**Define the component in the support APK manifest.**
+
+``` xml
+<manifest ...
+    package="org.chromium.chrome.tests.support" >
+
+  <application>
+    <service android:name="org.chromium.chrome.test.MyTestService"
+        android:exported="true"
+        tools:ignore="ExportedService">
+      ...
+    </service>
+
+    ...
+  </application>
+</manifest>
+```
+
+### Use a sharedUserId
+
+Using a [sharedUserId][3] will allow your component to run in your app's
+process.
+
+> Because this requires modifying the app manifest, it is not recommended at
+> this time and is intentionally not further documented here.
+
+[1]: https://developer.android.com/reference/android/content/ContentProvider.html
+[2]: https://developer.android.com/reference/android/app/Service.html
+[3]: https://developer.android.com/guide/topics/manifest/manifest-element.html#uid
diff --git a/testing/android/docs/instrumentation.md b/testing/android/docs/instrumentation.md
index c4e7c1942..458e03f5 100644
--- a/testing/android/docs/instrumentation.md
+++ b/testing/android/docs/instrumentation.md
@@ -289,3 +289,7 @@
 ```bash
 out/Debug/bin/run_chrome_public_test_apk -A Feature=Sync
 ```
+
+## Advanced
+
+ - [Creating a component for use in instrumentation tests.](/testing/android/docs/components_for_testing.md)
diff --git a/third_party/WebKit/LayoutTests/fast/shapedetection/shapedetection-creation.html b/third_party/WebKit/LayoutTests/fast/shapedetection/shapedetection-creation.html
index 3569b4f..fc4ac42 100644
--- a/third_party/WebKit/LayoutTests/fast/shapedetection/shapedetection-creation.html
+++ b/third_party/WebKit/LayoutTests/fast/shapedetection/shapedetection-creation.html
@@ -40,4 +40,16 @@
   assert_true(barcodeDetector instanceof BarcodeDetector);
 }, 'BarcodeDetector instance can be created.');
 
+// This test verifies that DetectedText can be created
+test(function() {
+  var detectedText = new DetectedText();
+  assert_true(detectedText instanceof DetectedText);
+}, 'DetectedText instance can be created.');
+
+// This test verifies that TextDetector can be created
+test(function() {
+  var textDetector = new TextDetector();
+  assert_true(textDetector instanceof TextDetector);
+}, 'TextDetector instance can be created.');
+
 </script>
diff --git a/third_party/WebKit/LayoutTests/fast/shapedetection/shapedetection-empty-input.html b/third_party/WebKit/LayoutTests/fast/shapedetection/shapedetection-empty-input.html
index b1270b1f..73b2ded6 100644
--- a/third_party/WebKit/LayoutTests/fast/shapedetection/shapedetection-empty-input.html
+++ b/third_party/WebKit/LayoutTests/fast/shapedetection/shapedetection-empty-input.html
@@ -25,7 +25,9 @@
 };
 
 generate_tests(createTestForEmptyInput, [
-  [ "Face", "FaceDetector" ], [ "Barcode", "BarcodeDetector" ]
+  [ "Face", "FaceDetector" ],
+  [ "Barcode", "BarcodeDetector" ],
+  [ "Text", "TextDetector" ]
 ]);
 
 </script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
index b3176d6..27de9fc2 100644
--- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -702,6 +702,9 @@
     getter ignoreBOM
     method constructor
     method decode
+interface TextDetector
+    method constructor
+    method detect
 interface TextEncoder
     getter encoding
     method constructor
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/browsers/origin/cross-origin-objects/cross-origin-objects-exceptions-expected.txt b/third_party/WebKit/LayoutTests/imported/wpt/html/browsers/origin/cross-origin-objects/cross-origin-objects-exceptions-expected.txt
index 3fe90b6..52c15904 100644
--- a/third_party/WebKit/LayoutTests/imported/wpt/html/browsers/origin/cross-origin-objects/cross-origin-objects-exceptions-expected.txt
+++ b/third_party/WebKit/LayoutTests/imported/wpt/html/browsers/origin/cross-origin-objects/cross-origin-objects-exceptions-expected.txt
@@ -10,7 +10,7 @@
 FAIL [[Delete]] Should throw on cross-origin objects assert_throws: Can't delete cross-origin indexed property function "function () { delete C[0]; }" did not throw
 FAIL [[DefineOwnProperty]] Should throw for cross-origin objects assert_throws: Can't define cross-origin value property length function "function () { Object.defineProperty(obj, prop, valueDesc); }" did not throw
 FAIL [[Enumerate]] should return an empty iterator assert_unreached: Shouldn't have been able to enumerate stop on cross-origin Window Reached unreachable code
-FAIL [[OwnPropertyKeys]] should return all properties from cross-origin objects assert_array_equals: Object.getOwnPropertyNames() gives the right answer for cross-origin Window lengths differ, expected 871 got 13
+FAIL [[OwnPropertyKeys]] should return all properties from cross-origin objects assert_array_equals: Object.getOwnPropertyNames() gives the right answer for cross-origin Window lengths differ, expected 872 got 13
 PASS A and B jointly observe the same identity for cross-origin Window and Location 
 PASS Cross-origin functions get local Function.prototype 
 FAIL Cross-origin Window accessors get local Function.prototype Cannot read property 'name' of undefined
diff --git a/third_party/WebKit/LayoutTests/payments/payment-request-interface.html b/third_party/WebKit/LayoutTests/payments/payment-request-interface.html
index dcab558c..5f82a3a 100644
--- a/third_party/WebKit/LayoutTests/payments/payment-request-interface.html
+++ b/third_party/WebKit/LayoutTests/payments/payment-request-interface.html
@@ -270,12 +270,32 @@
 }, 'Android Pay parameters for produciton environment with network token should not throw.');
 
 test(function() {
+  new PaymentRequest([{'supportedMethods': ['basic-card'], 'data': {'supportedTypes': ['debit'], 'supportedNetworks': ['visa']}}], buildDetails());
+}, 'Basic card parameters should not throw.');
+
+test(function() {
+  new PaymentRequest([{'supportedMethods': ['basic-card'], 'data': {'supportedTypes': [], 'supportedNetworks': []}}], buildDetails());
+}, 'Empty basic card parameters should not throw.');
+
+test(function() {
+  new PaymentRequest([{'supportedMethods': ['not-basic-card'], 'data': {'supportedTypes': 0, 'supportedNetworks': 'foo'}}], buildDetails());
+}, 'Invalid basic card parameters should not throw when method name is not "basic-card".');
+
+test(function() {
+  new PaymentRequest([{'supportedMethods': ['basic-card'], 'data': {'supportedTypes': 0, 'supportedNetworks': 'foo'}}], buildDetails());
+}, 'Invalid basic card parameters should not throw even when method name is "basic-card".');
+
+test(function() {
     new PaymentRequest([{'supportedMethods': ['https://android.com/pay'], 'data': {'merchantName': 'Merchant Inc', 'merchantId': '123', 'allowedCardNetworks': ['AMEX', 'DISCOVER', 'MASTERCARD', 'VISA'], 'paymentMethodTokenizationParameters': {'tokenizationType': 'NETWORK_TOKEN', 'parameters': {'key': 'value'}}}}], buildDetails());
 }, 'Android Pay parameters for network token without environment key should not throw.');
 
 test(function() {
-    new PaymentRequest([{'supportedMethods': ['https://android.com/pay'], 'data': {'merchantName': []}}], buildDetails());
-}, 'Invalid Android Pay parameters should not throw.');
+    new PaymentRequest([{'supportedMethods': ['https://bobpay.com'], 'data': {'allowedCardNetworks': 0}}], buildDetails());
+}, 'Invalid Android Pay parameters should not throw when method name is not "https://android.com/pay".');
+
+test(function() {
+    new PaymentRequest([{'supportedMethods': ['https://android.com/pay'], 'data': {'allowedCardNetworks': 0}}], buildDetails());
+}, 'Invalid Android Pay parameters should not throw even when method name is "https://android.com/pay".');
 
 promise_test(function(t) {
     return promise_rejects(t, null, new PaymentRequest([{'supportedMethods': ['foo']}], buildDetails()).abort());
diff --git a/third_party/WebKit/LayoutTests/shapedetection/detection-HTMLCanvasElement.html b/third_party/WebKit/LayoutTests/shapedetection/detection-HTMLCanvasElement.html
index 5c030ddc..4edb729 100644
--- a/third_party/WebKit/LayoutTests/shapedetection/detection-HTMLCanvasElement.html
+++ b/third_party/WebKit/LayoutTests/shapedetection/detection-HTMLCanvasElement.html
@@ -4,6 +4,7 @@
 <script src="../resources/mojo-helpers.js"></script>
 <script src="resources/mock-barcodedetection.js"></script>
 <script src="resources/mock-facedetection.js"></script>
+<script src="resources/mock-textdetection.js"></script>
 <script>
 
 var createTestForCanvasElement = function(createDetector,
@@ -58,6 +59,12 @@
   assert_equals(detectionResult[1].rawValue, "dogs", "barcode 2");
 }
 
+function TextDetectorDetectionResultTest(detectionResult, mock) {
+  assert_equals(detectionResult.length, 2, "Number of textBlocks");
+  assert_equals(detectionResult[0].rawValue, "cats", "textBlock 1");
+  assert_equals(detectionResult[1].rawValue, "dogs", "textBlock 2");
+}
+
 // These tests verify that a Detector's detect() works on an HTMLCanvasElement
 // and on an OffscreenCanvas. Use the mock mojo server implemented in
 // mock-{barcode,face}detection.js.
@@ -89,6 +96,20 @@
     () => { return new OffscreenCanvas(300, 150); },
     () => { return mockBarcodeDetectionReady; },
     BarcodeDetectorDetectionResultTest
+  ],
+  [
+    "Text - HTMLCanvasElement",
+    () => { return new TextDetector(); },
+    () => { return document.createElement("canvas"); },
+    () => { return mockTextDetectionReady; },
+    TextDetectorDetectionResultTest
+  ],
+  [
+    "Text - OffscreenCanvas",
+    () => { return new TextDetector(); },
+    () => { return new OffscreenCanvas(300, 150); },
+    () => { return mockTextDetectionReady; },
+    TextDetectorDetectionResultTest
   ]
 ]);
 
diff --git a/third_party/WebKit/LayoutTests/shapedetection/detection-HTMLImageElement.html b/third_party/WebKit/LayoutTests/shapedetection/detection-HTMLImageElement.html
index c4ab7b5b..e84cbf2 100644
--- a/third_party/WebKit/LayoutTests/shapedetection/detection-HTMLImageElement.html
+++ b/third_party/WebKit/LayoutTests/shapedetection/detection-HTMLImageElement.html
@@ -4,6 +4,7 @@
 <script src="../resources/mojo-helpers.js"></script>
 <script src="resources/mock-barcodedetection.js"></script>
 <script src="resources/mock-facedetection.js"></script>
+<script src="resources/mock-textdetection.js"></script>
 <body>
 <img id="img" src="../media/content/greenbox.png"/>
 </body>
@@ -52,6 +53,12 @@
   assert_equals(detectionResult[1].rawValue, "dogs", "barcode 2");
 }
 
+function TextDetectorDetectionResultTest(detectionResult, mock) {
+  assert_equals(detectionResult.length, 2, "Number of textBlocks");
+  assert_equals(detectionResult[0].rawValue, "cats", "textBlock 1");
+  assert_equals(detectionResult[1].rawValue, "dogs", "textBlock 2");
+}
+
 // These tests verify that a Detector's detect() works on an HTMLImageElement.
 // Use the mock mojo server implemented in mock-{barcode,face}detection.js.
 generate_tests(createTestForImageElement, [
@@ -66,6 +73,12 @@
     () => { return new BarcodeDetector(); },
     () => { return mockBarcodeDetectionReady; },
     BarcodeDetectorDetectionResultTest
+  ],
+  [
+    "Text",
+    () => { return new TextDetector(); },
+    () => { return mockTextDetectionReady; },
+    TextDetectorDetectionResultTest
   ]
 ]);
 
diff --git a/third_party/WebKit/LayoutTests/shapedetection/detection-HTMLVideoElement.html b/third_party/WebKit/LayoutTests/shapedetection/detection-HTMLVideoElement.html
index aafd565..92465e3 100644
--- a/third_party/WebKit/LayoutTests/shapedetection/detection-HTMLVideoElement.html
+++ b/third_party/WebKit/LayoutTests/shapedetection/detection-HTMLVideoElement.html
@@ -4,6 +4,7 @@
 <script src="../resources/mojo-helpers.js"></script>
 <script src="resources/mock-barcodedetection.js"></script>
 <script src="resources/mock-facedetection.js"></script>
+<script src="resources/mock-textdetection.js"></script>
 <script>
 
 var createTestForVideoElement = function(createDetector, mockReady,
@@ -56,6 +57,12 @@
   assert_equals(detectionResult[1].rawValue, "dogs", "barcode 2");
 }
 
+function TextDetectorDetectionResultTest(detectionResult, mock) {
+  assert_equals(detectionResult.length, 2, "Number of textBlocks");
+  assert_equals(detectionResult[0].rawValue, "cats", "textBlock 1");
+  assert_equals(detectionResult[1].rawValue, "dogs", "textBlock 2");
+}
+
 // These tests verify that a Detector's detect() works on an HTMLVideoElement.
 // Use the mock mojo server implemented in mock-{barcode,face}detection.js.
 generate_tests(createTestForVideoElement, [
@@ -70,6 +77,12 @@
     () => { return new BarcodeDetector(); },
     () => { return mockBarcodeDetectionReady; },
     BarcodeDetectorDetectionResultTest
+  ],
+  [
+    "Text",
+    () => { return new TextDetector(); },
+    () => { return mockTextDetectionReady; },
+    TextDetectorDetectionResultTest
   ]
 ]);
 
diff --git a/third_party/WebKit/LayoutTests/shapedetection/detection-ImageBitmap.html b/third_party/WebKit/LayoutTests/shapedetection/detection-ImageBitmap.html
index 18c364ee..62e20de 100644
--- a/third_party/WebKit/LayoutTests/shapedetection/detection-ImageBitmap.html
+++ b/third_party/WebKit/LayoutTests/shapedetection/detection-ImageBitmap.html
@@ -4,6 +4,7 @@
 <script src="../resources/mojo-helpers.js"></script>
 <script src="resources/mock-barcodedetection.js"></script>
 <script src="resources/mock-facedetection.js"></script>
+<script src="resources/mock-textdetection.js"></script>
 <script>
 
 var createTestForImageBitmap = function(createDetector, mockReady,
@@ -60,6 +61,12 @@
   assert_equals(detectionResult[1].rawValue, "dogs", "barcode 2");
 }
 
+function TextDetectorDetectionResultTest(detectionResult, mock) {
+  assert_equals(detectionResult.length, 2, "Number of textBlocks");
+  assert_equals(detectionResult[0].rawValue, "cats", "textBlock 1");
+  assert_equals(detectionResult[1].rawValue, "dogs", "textBlock 2");
+}
+
 // These tests verify that a Detector's detect() works on an ImageBitmap.
 // Use the mock mojo server implemented in mock-{barcode,face}detection.js.
 generate_tests(createTestForImageBitmap, [
@@ -74,6 +81,12 @@
     () => { return new BarcodeDetector(); },
     () => { return mockBarcodeDetectionReady; },
     BarcodeDetectorDetectionResultTest
+  ],
+  [
+    "Text",
+    () => { return new TextDetector(); },
+    () => { return mockTextDetectionReady; },
+    TextDetectorDetectionResultTest
   ]
 ]);
 
diff --git a/third_party/WebKit/LayoutTests/shapedetection/detection-ImageData.html b/third_party/WebKit/LayoutTests/shapedetection/detection-ImageData.html
index 45842af..9f0b9361 100644
--- a/third_party/WebKit/LayoutTests/shapedetection/detection-ImageData.html
+++ b/third_party/WebKit/LayoutTests/shapedetection/detection-ImageData.html
@@ -4,6 +4,7 @@
 <script src="../resources/mojo-helpers.js"></script>
 <script src="resources/mock-barcodedetection.js"></script>
 <script src="resources/mock-facedetection.js"></script>
+<script src="resources/mock-textdetection.js"></script>
 <script>
 
 var createTestForImageData = function(createDetector, mockReady,
@@ -57,6 +58,12 @@
   assert_equals(detectionResult[1].rawValue, "dogs", "barcode 2");
 }
 
+function TextDetectorDetectionResultTest(detectionResult, mock) {
+  assert_equals(detectionResult.length, 2, "Number of textBlocks");
+  assert_equals(detectionResult[0].rawValue, "cats", "textBlock 1");
+  assert_equals(detectionResult[1].rawValue, "dogs", "textBlock 2");
+}
+
 // These tests verify that a Detector's detect() works on an ImageBitmap. Use
 // the mock mojo server implemented in mock-{barcode,face}detection.js.
 generate_tests(createTestForImageData, [
@@ -72,6 +79,12 @@
     () => { return mockBarcodeDetectionReady; },
     BarcodeDetectorDetectionResultTest
   ],
+  [
+    "Text",
+    () => { return new TextDetector(); },
+    () => { return mockTextDetectionReady; },
+    TextDetectorDetectionResultTest
+  ]
 ]);
 
 </script>
diff --git a/third_party/WebKit/LayoutTests/shapedetection/resources/mock-facedetection.js b/third_party/WebKit/LayoutTests/shapedetection/resources/mock-facedetection.js
index 62220e8..298f7e4 100644
--- a/third_party/WebKit/LayoutTests/shapedetection/resources/mock-facedetection.js
+++ b/third_party/WebKit/LayoutTests/shapedetection/resources/mock-facedetection.js
@@ -50,9 +50,9 @@
       return Promise.resolve({
         result: {
           bounding_boxes: [
-              { x : 1.0, y: 1.0, width: 100.0, height: 100.0 },
-              { x : 2.0, y: 2.0, width: 200.0, height: 200.0 },
-              { x : 3.0, y: 3.0, width: 300.0, height: 300.0 },
+            { x : 1.0, y: 1.0, width: 100.0, height: 100.0 },
+            { x : 2.0, y: 2.0, width: 200.0, height: 200.0 },
+            { x : 3.0, y: 3.0, width: 300.0, height: 300.0 },
           ]
         }
       });
diff --git a/third_party/WebKit/LayoutTests/shapedetection/resources/mock-textdetection.js b/third_party/WebKit/LayoutTests/shapedetection/resources/mock-textdetection.js
new file mode 100644
index 0000000..06bc811
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/shapedetection/resources/mock-textdetection.js
@@ -0,0 +1,43 @@
+"use strict";
+
+let mockTextDetectionReady = define(
+  'mockTextDetection',
+  ['third_party/WebKit/public/platform/modules/shapedetection/textdetection.mojom',
+   'mojo/public/js/bindings',
+   'mojo/public/js/core',
+   'content/public/renderer/frame_interfaces',
+  ], (textDetection, bindings, mojo, interfaces) => {
+
+  class MockTextDetection {
+    constructor() {
+      this.bindingSet_ = new bindings.BindingSet(textDetection.TextDetection);
+
+      interfaces.addInterfaceOverrideForTesting(
+          textDetection.TextDetection.name,
+          handle => this.bindingSet_.addBinding(this, handle));
+    }
+
+    detect(frame_data, width, height) {
+      let receivedStruct = mojo.mapBuffer(frame_data, 0, width*height*4, 0);
+      this.buffer_data_ = new Uint32Array(receivedStruct.buffer);
+      return Promise.resolve({
+        results: [
+          {
+            raw_value : "cats",
+            bounding_box: { x: 1.0, y: 1.0, width: 100.0, height: 100.0 }
+          },
+          {
+            raw_value : "dogs",
+            bounding_box: { x: 2.0, y: 2.0, width: 50.0, height: 50.0 }
+          },
+        ],
+      });
+      mojo.unmapBuffer(receivedStruct.buffer);
+    }
+
+    getFrameData() {
+      return this.buffer_data_;
+    }
+  }
+  return new MockTextDetection();
+});
diff --git a/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
index 0bd8e77..f7ca39b 100644
--- a/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -710,6 +710,9 @@
     getter ignoreBOM
     method constructor
     method decode
+interface TextDetector
+    method constructor
+    method detect
 interface TextEncoder
     getter encoding
     method constructor
diff --git a/third_party/WebKit/LayoutTests/vr/getVRDisplays_always_resolves.html b/third_party/WebKit/LayoutTests/vr/getVRDisplays_always_resolves.html
deleted file mode 100644
index ea26338..0000000
--- a/third_party/WebKit/LayoutTests/vr/getVRDisplays_always_resolves.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<!DOCTYPE html>
-<script src="../resources/testharness.js"></script>
-<script src="../resources/testharnessreport.js"></script>
-<script>
-
-promise_test(t => navigator.getVRDisplays().then(devices => {
-  assert_true(devices != null);
-  assert_true(devices instanceof Array);
-  assert_greater_than_equal(0, devices.length);
-
-  if (devices.length > 0)
-    assert_true(devices[0] instanceof VRDisplay);
-}), "Test that getVRDisplays always resolves with at least an empty sequence.");
-
-</script>
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt
index b99ecb9..a71964a 100644
--- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt
@@ -701,6 +701,10 @@
 [Worker]     getter ignoreBOM
 [Worker]     method constructor
 [Worker]     method decode
+[Worker] interface TextDetector
+[Worker]     attribute @@toStringTag
+[Worker]     method constructor
+[Worker]     method detect
 [Worker] interface TextEncoder
 [Worker]     attribute @@toStringTag
 [Worker]     getter encoding
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
index bcb31bb4..cbfdd6b1 100644
--- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -1246,6 +1246,11 @@
     attribute @@toStringTag
     getter boundingBox
     method constructor
+interface DetectedText
+    attribute @@toStringTag
+    getter boundingBox
+    getter rawValue
+    method constructor
 interface DeviceLightEvent : Event
     attribute @@toStringTag
     getter value
@@ -3925,7 +3930,7 @@
     setter onresume
     setter onstart
     setter onstop
-interface MediaSession : EventTarget
+interface MediaSession
     attribute @@toStringTag
     getter metadata
     getter playbackState
@@ -6468,6 +6473,10 @@
     getter ignoreBOM
     method constructor
     method decode
+interface TextDetector
+    attribute @@toStringTag
+    method constructor
+    method detect
 interface TextEncoder
     attribute @@toStringTag
     getter encoding
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt
index ce018f0..0e9045a 100644
--- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt
@@ -701,6 +701,10 @@
 [Worker]     getter ignoreBOM
 [Worker]     method constructor
 [Worker]     method decode
+[Worker] interface TextDetector
+[Worker]     attribute @@toStringTag
+[Worker]     method constructor
+[Worker]     method detect
 [Worker] interface TextEncoder
 [Worker]     attribute @@toStringTag
 [Worker]     getter encoding
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptPromiseProperty.h b/third_party/WebKit/Source/bindings/core/v8/ScriptPromiseProperty.h
index e3e17ba..f979119 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptPromiseProperty.h
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptPromiseProperty.h
@@ -105,6 +105,7 @@
     NOTREACHED();
     return;
   }
+  DCHECK(!ScriptForbiddenScope::isScriptForbidden());
   if (!getExecutionContext() || getExecutionContext()->isContextDestroyed())
     return;
   m_resolved = value;
diff --git a/third_party/WebKit/Source/build/scripts/templates/CSSOMKeywords.cpp.tmpl b/third_party/WebKit/Source/build/scripts/templates/CSSOMKeywords.cpp.tmpl
index 2a631b3..7762728 100644
--- a/third_party/WebKit/Source/build/scripts/templates/CSSOMKeywords.cpp.tmpl
+++ b/third_party/WebKit/Source/build/scripts/templates/CSSOMKeywords.cpp.tmpl
@@ -21,7 +21,7 @@
   {
     Vector<CSSValueID> {{property.lower_camel_name}}Keywords;
     {% for keywordValueID in property.keywordIDs %}
-    {{property.lower_camel_name}}Keywords.append({{keywordValueID}});
+    {{property.lower_camel_name}}Keywords.push_back({{keywordValueID}});
     {% endfor %}
     table.set({{property_id}}, {{property.lower_camel_name}}Keywords);
   }
diff --git a/third_party/WebKit/Source/build/scripts/templates/CSSPropertyMetadata.cpp.tmpl b/third_party/WebKit/Source/build/scripts/templates/CSSPropertyMetadata.cpp.tmpl
index b9fe6ea..cc7ea78 100644
--- a/third_party/WebKit/Source/build/scripts/templates/CSSPropertyMetadata.cpp.tmpl
+++ b/third_party/WebKit/Source/build/scripts/templates/CSSPropertyMetadata.cpp.tmpl
@@ -58,7 +58,7 @@
   for (unsigned i = 0; i < propertyCount; i++) {
     CSSPropertyID property = properties[i];
     if (isEnabledProperty(property))
-      outVector.append(property);
+      outVector.push_back(property);
   }
 }
 
diff --git a/third_party/WebKit/Source/build/scripts/templates/StyleBuilderFunctions.cpp.tmpl b/third_party/WebKit/Source/build/scripts/templates/StyleBuilderFunctions.cpp.tmpl
index 2b20218..cd22357 100644
--- a/third_party/WebKit/Source/build/scripts/templates/StyleBuilderFunctions.cpp.tmpl
+++ b/third_party/WebKit/Source/build/scripts/templates/StyleBuilderFunctions.cpp.tmpl
@@ -100,7 +100,7 @@
 {{declare_initial_function(property_id)}} {
   CSS{{animation}}Data& data = state.style()->access{{animation}}s();
   data.{{vector}}.clear();
-  data.{{vector}}.append(CSS{{animation}}Data::initial{{attribute}}());
+  data.{{vector}}.push_back(CSS{{animation}}Data::initial{{attribute}}());
 }
 
 {{declare_inherit_function(property_id)}} {
@@ -115,7 +115,7 @@
   CSS{{animation}}Data& data = state.style()->access{{animation}}s();
   data.{{vector}}.clear();
   for (auto& listValue : toCSSValueList(value))
-    data.{{vector}}.append(CSSToStyleMap::mapAnimation{{attribute}}(*listValue));
+    data.{{vector}}.push_back(CSSToStyleMap::mapAnimation{{attribute}}(*listValue));
 }
 {% endmacro %}
 {{apply_animation('CSSPropertyAnimationDelay', 'Delay', 'Animation')}}
diff --git a/third_party/WebKit/Source/core/animation/Animation.cpp b/third_party/WebKit/Source/core/animation/Animation.cpp
index 5af7bf2..6542483 100644
--- a/third_party/WebKit/Source/core/animation/Animation.cpp
+++ b/third_party/WebKit/Source/core/animation/Animation.cpp
@@ -37,12 +37,15 @@
 #include "core/dom/Document.h"
 #include "core/dom/ExceptionCode.h"
 #include "core/dom/StyleChangeReason.h"
+#include "core/dom/TaskRunnerHelper.h"
 #include "core/events/AnimationPlaybackEvent.h"
 #include "core/frame/UseCounter.h"
 #include "core/inspector/InspectorInstrumentation.h"
 #include "core/inspector/InspectorTraceEvents.h"
 #include "platform/RuntimeEnabledFeatures.h"
+#include "platform/WebTaskRunner.h"
 #include "platform/animation/CompositorAnimationPlayer.h"
+#include "platform/heap/Persistent.h"
 #include "platform/instrumentation/tracing/TraceEvent.h"
 #include "public/platform/Platform.h"
 #include "public/platform/WebCompositorSupport.h"
@@ -650,7 +653,7 @@
 
 bool Animation::hasPendingActivity() const {
   bool hasPendingPromise =
-      !m_finished && m_finishedPromise &&
+      m_finishedPromise &&
       m_finishedPromise->getState() == ScriptPromisePropertyBase::Pending;
 
   return m_pendingFinishedEvent || hasPendingPromise ||
@@ -1012,9 +1015,9 @@
         m_animation->m_readyPromise->reject(DOMException::create(AbortError));
       }
       m_animation->m_readyPromise->reset();
-      m_animation->m_readyPromise->resolve(m_animation);
+      m_animation->resolvePromiseAsync(m_animation->m_readyPromise.get());
     } else if (oldPlayState == Pending) {
-      m_animation->m_readyPromise->resolve(m_animation);
+      m_animation->resolvePromiseAsync(m_animation->m_readyPromise.get());
     } else if (newPlayState == Pending) {
       DCHECK_NE(m_animation->m_readyPromise->getState(),
                 AnimationPromise::Pending);
@@ -1031,7 +1034,7 @@
       }
       m_animation->m_finishedPromise->reset();
     } else if (newPlayState == Finished) {
-      m_animation->m_finishedPromise->resolve(m_animation);
+      m_animation->resolvePromiseAsync(m_animation->m_finishedPromise.get());
     } else if (oldPlayState == Finished) {
       m_animation->m_finishedPromise->reset();
     }
@@ -1109,6 +1112,13 @@
                                    StyleChangeReason::StyleSheetChange));
 }
 
+void Animation::resolvePromiseAsync(AnimationPromise* promise) {
+  TaskRunnerHelper::get(TaskType::DOMManipulation, getExecutionContext())
+      ->postTask(BLINK_FROM_HERE,
+                 WTF::bind(&AnimationPromise::resolve<Animation*>,
+                           wrapPersistent(promise), wrapPersistent(this)));
+}
+
 DEFINE_TRACE(Animation) {
   visitor->trace(m_content);
   visitor->trace(m_timeline);
diff --git a/third_party/WebKit/Source/core/animation/Animation.h b/third_party/WebKit/Source/core/animation/Animation.h
index 339209ee..927e4ff 100644
--- a/third_party/WebKit/Source/core/animation/Animation.h
+++ b/third_party/WebKit/Source/core/animation/Animation.h
@@ -221,6 +221,11 @@
   void notifyAnimationFinished(double monotonicTime, int group) override {}
   void notifyAnimationAborted(double monotonicTime, int group) override {}
 
+  using AnimationPromise = ScriptPromiseProperty<Member<Animation>,
+                                                 Member<Animation>,
+                                                 Member<DOMException>>;
+  void resolvePromiseAsync(AnimationPromise*);
+
   String m_id;
 
   AnimationPlayState m_playState;
@@ -230,10 +235,6 @@
 
   unsigned m_sequenceNumber;
 
-  typedef ScriptPromiseProperty<Member<Animation>,
-                                Member<Animation>,
-                                Member<DOMException>>
-      AnimationPromise;
   Member<AnimationPromise> m_finishedPromise;
   Member<AnimationPromise> m_readyPromise;
 
diff --git a/third_party/WebKit/Source/core/animation/ElementAnimation.h b/third_party/WebKit/Source/core/animation/ElementAnimation.h
index 9f83d184..971a1f05 100644
--- a/third_party/WebKit/Source/core/animation/ElementAnimation.h
+++ b/third_party/WebKit/Source/core/animation/ElementAnimation.h
@@ -32,6 +32,7 @@
 #define ElementAnimation_h
 
 #include "bindings/core/v8/DictionarySequenceOrDictionary.h"
+#include "bindings/core/v8/ScriptState.h"
 #include "core/animation/DocumentTimeline.h"
 #include "core/animation/EffectInput.h"
 #include "core/animation/ElementAnimations.h"
@@ -50,13 +51,14 @@
   STATIC_ONLY(ElementAnimation);
 
  public:
-  static Animation* animate(ExecutionContext* executionContext,
+  static Animation* animate(ScriptState* scriptState,
                             Element& element,
                             const DictionarySequenceOrDictionary& effectInput,
                             double duration,
                             ExceptionState& exceptionState) {
     EffectModel* effect = EffectInput::convert(
-        &element, effectInput, executionContext, exceptionState);
+        &element, effectInput, scriptState->getExecutionContext(),
+        exceptionState);
     if (exceptionState.hadException())
       return nullptr;
 
@@ -67,13 +69,14 @@
     return animateInternal(element, effect, timing);
   }
 
-  static Animation* animate(ExecutionContext* executionContext,
+  static Animation* animate(ScriptState* scriptState,
                             Element& element,
                             const DictionarySequenceOrDictionary& effectInput,
                             const KeyframeEffectOptions& options,
                             ExceptionState& exceptionState) {
     EffectModel* effect = EffectInput::convert(
-        &element, effectInput, executionContext, exceptionState);
+        &element, effectInput, scriptState->getExecutionContext(),
+        exceptionState);
     if (exceptionState.hadException())
       return nullptr;
 
@@ -87,12 +90,13 @@
     return animation;
   }
 
-  static Animation* animate(ExecutionContext* executionContext,
+  static Animation* animate(ScriptState* scriptState,
                             Element& element,
                             const DictionarySequenceOrDictionary& effectInput,
                             ExceptionState& exceptionState) {
     EffectModel* effect = EffectInput::convert(
-        &element, effectInput, executionContext, exceptionState);
+        &element, effectInput, scriptState->getExecutionContext(),
+        exceptionState);
     if (exceptionState.hadException())
       return nullptr;
     return animateInternal(element, effect, Timing());
diff --git a/third_party/WebKit/Source/core/animation/ElementAnimation.idl b/third_party/WebKit/Source/core/animation/ElementAnimation.idl
index 3c5e42ba..d66c98b 100644
--- a/third_party/WebKit/Source/core/animation/ElementAnimation.idl
+++ b/third_party/WebKit/Source/core/animation/ElementAnimation.idl
@@ -38,7 +38,7 @@
 partial interface Element {
     // FIXME: Union types with dictionary type members doesn't work (yet).
     // Animation animate((sequence<Dictionary> or Dictionary)? effect, optional (double or KeyframeEffectOptions) timing);
-    [CallWith=ExecutionContext, Measure, RaisesException] Animation animate((sequence<Dictionary> or Dictionary)? effect, optional double timing);
-    [CallWith=ExecutionContext, Measure, RaisesException] Animation animate((sequence<Dictionary> or Dictionary)? effect, KeyframeEffectOptions timing);
+    [CallWith=ScriptState, Measure, RaisesException] Animation animate((sequence<Dictionary> or Dictionary)? effect, optional double timing);
+    [CallWith=ScriptState, Measure, RaisesException] Animation animate((sequence<Dictionary> or Dictionary)? effect, KeyframeEffectOptions timing);
     [RuntimeEnabled=WebAnimationsAPI] sequence<Animation> getAnimations();
 };
diff --git a/third_party/WebKit/Source/core/clipboard/DataTransferItem.cpp b/third_party/WebKit/Source/core/clipboard/DataTransferItem.cpp
index 46c47d0..87b91de 100644
--- a/third_party/WebKit/Source/core/clipboard/DataTransferItem.cpp
+++ b/third_party/WebKit/Source/core/clipboard/DataTransferItem.cpp
@@ -69,14 +69,14 @@
   return m_item->type();
 }
 
-void DataTransferItem::getAsString(ExecutionContext* context,
+void DataTransferItem::getAsString(ScriptState* scriptState,
                                    StringCallback* callback) const {
   if (!m_dataTransfer->canReadData())
     return;
   if (!callback || m_item->kind() != DataObjectItem::StringKind)
     return;
 
-  context->postTask(
+  scriptState->getExecutionContext()->postTask(
       TaskType::UserInteraction, BLINK_FROM_HERE,
       createSameThreadTask(&StringCallback::handleEvent,
                            wrapPersistent(callback), m_item->getAsString()),
diff --git a/third_party/WebKit/Source/core/clipboard/DataTransferItem.h b/third_party/WebKit/Source/core/clipboard/DataTransferItem.h
index 348820ac..4fcffa02 100644
--- a/third_party/WebKit/Source/core/clipboard/DataTransferItem.h
+++ b/third_party/WebKit/Source/core/clipboard/DataTransferItem.h
@@ -41,8 +41,8 @@
 class Blob;
 class DataObjectItem;
 class DataTransfer;
+class ScriptState;
 class StringCallback;
-class ExecutionContext;
 
 class CORE_EXPORT DataTransferItem final
     : public GarbageCollected<DataTransferItem>,
@@ -56,7 +56,7 @@
   String kind() const;
   String type() const;
 
-  void getAsString(ExecutionContext*, StringCallback*) const;
+  void getAsString(ScriptState*, StringCallback*) const;
   Blob* getAsFile() const;
 
   DataTransfer* getDataTransfer() { return m_dataTransfer.get(); }
diff --git a/third_party/WebKit/Source/core/clipboard/DataTransferItem.idl b/third_party/WebKit/Source/core/clipboard/DataTransferItem.idl
index f30a2ca..01f50656 100644
--- a/third_party/WebKit/Source/core/clipboard/DataTransferItem.idl
+++ b/third_party/WebKit/Source/core/clipboard/DataTransferItem.idl
@@ -34,7 +34,7 @@
     readonly attribute DOMString kind;
     readonly attribute DOMString type;
     // TODO(foolip): The callback argument should be a FunctionStringCallback.
-    [CallWith=ExecutionContext] void getAsString(StringCallback? callback);
+    [CallWith=ScriptState] void getAsString(StringCallback? callback);
     // TODO(foolip): getAsFile() should return a File object. crbug.com/361145
     Blob? getAsFile();
 };
diff --git a/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.cpp b/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.cpp
index d8781a29..2b27368 100644
--- a/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.cpp
+++ b/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.cpp
@@ -1032,7 +1032,7 @@
 
   ShadowDataVector shadows;
   for (const auto& item : toCSSValueList(value))
-    shadows.append(convertShadow(state, *item));
+    shadows.push_back(convertShadow(state, *item));
 
   return ShadowList::adopt(shadows);
 }
diff --git a/third_party/WebKit/Source/core/dom/DOMStringList.cpp b/third_party/WebKit/Source/core/dom/DOMStringList.cpp
index 4350e60b..de258f5 100644
--- a/third_party/WebKit/Source/core/dom/DOMStringList.cpp
+++ b/third_party/WebKit/Source/core/dom/DOMStringList.cpp
@@ -25,7 +25,7 @@
 
 #include "core/dom/DOMStringList.h"
 
-#include "core/dom/ExecutionContext.h"
+#include "bindings/core/v8/ScriptState.h"
 #include "core/frame/UseCounter.h"
 #include <algorithm>
 
@@ -37,15 +37,17 @@
   return m_strings[index];
 }
 
-String DOMStringList::item(ExecutionContext* context, unsigned index) const {
+String DOMStringList::item(ScriptState* scriptState, unsigned index) const {
   switch (m_source) {
     case DOMStringList::IndexedDB:
       UseCounter::count(
-          context, UseCounter::DOMStringList_Item_AttributeGetter_IndexedDB);
+          scriptState->getExecutionContext(),
+          UseCounter::DOMStringList_Item_AttributeGetter_IndexedDB);
       break;
     case DOMStringList::Location:
       UseCounter::count(
-          context, UseCounter::DOMStringList_Item_AttributeGetter_Location);
+          scriptState->getExecutionContext(),
+          UseCounter::DOMStringList_Item_AttributeGetter_Location);
       break;
     default:
       NOTREACHED();
@@ -54,15 +56,15 @@
   return anonymousIndexedGetter(index);
 }
 
-bool DOMStringList::contains(ExecutionContext* context,
+bool DOMStringList::contains(ScriptState* scriptState,
                              const String& string) const {
   switch (m_source) {
     case DOMStringList::IndexedDB:
-      UseCounter::count(context,
+      UseCounter::count(scriptState->getExecutionContext(),
                         UseCounter::DOMStringList_Contains_Method_IndexedDB);
       break;
     case DOMStringList::Location:
-      UseCounter::count(context,
+      UseCounter::count(scriptState->getExecutionContext(),
                         UseCounter::DOMStringList_Contains_Method_Location);
       break;
     default:
diff --git a/third_party/WebKit/Source/core/dom/DOMStringList.h b/third_party/WebKit/Source/core/dom/DOMStringList.h
index 23b43ae2..96da3e9 100644
--- a/third_party/WebKit/Source/core/dom/DOMStringList.h
+++ b/third_party/WebKit/Source/core/dom/DOMStringList.h
@@ -34,7 +34,7 @@
 
 namespace blink {
 
-class ExecutionContext;
+class ScriptState;
 
 // FIXME: Some consumers of this class may benefit from lazily fetching items
 // rather than creating the list statically as is currently the only option.
@@ -63,8 +63,8 @@
   size_t length() const { return m_strings.size(); }
   String anonymousIndexedGetter(unsigned index) const;
 
-  String item(ExecutionContext*, unsigned index) const;
-  bool contains(ExecutionContext*, const String&) const;
+  String item(ScriptState*, unsigned index) const;
+  bool contains(ScriptState*, const String&) const;
 
   operator const Vector<String>&() const { return m_strings; }
 
diff --git a/third_party/WebKit/Source/core/dom/DOMStringList.idl b/third_party/WebKit/Source/core/dom/DOMStringList.idl
index 887c5174..7d110b9 100644
--- a/third_party/WebKit/Source/core/dom/DOMStringList.idl
+++ b/third_party/WebKit/Source/core/dom/DOMStringList.idl
@@ -30,6 +30,6 @@
     readonly attribute unsigned long length;
     getter DOMString? (unsigned long index);
 
-    [CallWith=ExecutionContext] DOMString? item(unsigned long index);
-    [CallWith=ExecutionContext,MeasureAs=DOMStringListContains] boolean contains(DOMString string);
+    [CallWith=ScriptState] DOMString? item(unsigned long index);
+    [CallWith=ScriptState,MeasureAs=DOMStringListContains] boolean contains(DOMString string);
 };
diff --git a/third_party/WebKit/Source/core/dom/custom/CustomElementReactionStack.cpp b/third_party/WebKit/Source/core/dom/custom/CustomElementReactionStack.cpp
index b4641f0..8937bcc0 100644
--- a/third_party/WebKit/Source/core/dom/custom/CustomElementReactionStack.cpp
+++ b/third_party/WebKit/Source/core/dom/custom/CustomElementReactionStack.cpp
@@ -41,7 +41,7 @@
 }
 
 void CustomElementReactionStack::push() {
-  m_stack.append(nullptr);
+  m_stack.push_back(nullptr);
 }
 
 void CustomElementReactionStack::popInvokingReactions() {
@@ -73,7 +73,7 @@
                                          CustomElementReaction* reaction) {
   if (!queue)
     queue = new ElementQueue();
-  queue->append(element);
+  queue->push_back(element);
 
   CustomElementReactionQueue* reactions = m_map.get(element);
   if (!reactions) {
diff --git a/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp b/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp
index 653e52e..244af9b 100644
--- a/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp
+++ b/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp
@@ -327,7 +327,7 @@
   ensureComposition()->append(command->ensureComposition());
   command->m_composition = nullptr;
   command->setParent(this);
-  m_commands.append(command);
+  m_commands.push_back(command);
 }
 
 void CompositeEditCommand::applyStyle(const EditingStyle* style,
@@ -476,7 +476,7 @@
   HeapVector<Member<Node>> children;
   Node* child = NodeTraversal::childAt(*node, from);
   for (unsigned i = from; child && i < to; i++, child = child->nextSibling())
-    children.append(child);
+    children.push_back(child);
 
   size_t size = children.size();
   for (size_t i = 0; i < size; ++i) {
@@ -528,7 +528,7 @@
   NodeVector nodesToRemove;
 
   for (; node && node != pastLastNodeToMove; node = node->nextSibling())
-    nodesToRemove.append(node);
+    nodesToRemove.push_back(node);
 
   for (unsigned i = 0; i < nodesToRemove.size(); i++) {
     removeNode(nodesToRemove[i], editingState);
@@ -677,8 +677,8 @@
   types.reserveCapacity(arraySize);
   descriptions.reserveCapacity(arraySize);
   for (const auto& markerPointer : markerPointers) {
-    types.append(markerPointer->type());
-    descriptions.append(markerPointer->description());
+    types.push_back(markerPointer->type());
+    descriptions.push_back(markerPointer->description());
   }
 }
 
@@ -973,7 +973,7 @@
 
   for (InlineTextBox* textBox = textLayoutObject->firstTextBox(); textBox;
        textBox = textBox->nextTextBox())
-    sortedTextBoxes.append(textBox);
+    sortedTextBoxes.push_back(textBox);
 
   // If there is mixed directionality text, the boxes can be out of order,
   // (like Arabic with embedded LTR), so sort them first.
@@ -1053,7 +1053,7 @@
   HeapVector<Member<Text>> nodes;
   for (Node& node : NodeTraversal::startsAt(*start.anchorNode())) {
     if (node.isTextNode())
-      nodes.append(toText(&node));
+      nodes.push_back(toText(&node));
     if (&node == end.anchorNode())
       break;
   }
@@ -1304,7 +1304,7 @@
          NodeTraversal::inclusiveAncestorsOf(*start.anchorNode())) {
       if (runner == outerNode)
         break;
-      ancestors.append(runner);
+      ancestors.push_back(runner);
     }
 
     // Clone every node between start.anchorNode() and outerBlock.
diff --git a/third_party/WebKit/Source/core/fileapi/FileReaderSync.cpp b/third_party/WebKit/Source/core/fileapi/FileReaderSync.cpp
index 236cde0b..2b967df96 100644
--- a/third_party/WebKit/Source/core/fileapi/FileReaderSync.cpp
+++ b/third_party/WebKit/Source/core/fileapi/FileReaderSync.cpp
@@ -31,6 +31,7 @@
 #include "core/fileapi/FileReaderSync.h"
 
 #include "bindings/core/v8/ExceptionState.h"
+#include "bindings/core/v8/ScriptState.h"
 #include "core/dom/DOMArrayBuffer.h"
 #include "core/fileapi/Blob.h"
 #include "core/fileapi/FileError.h"
@@ -41,30 +42,32 @@
 FileReaderSync::FileReaderSync() {}
 
 DOMArrayBuffer* FileReaderSync::readAsArrayBuffer(
-    ExecutionContext* executionContext,
+    ScriptState* scriptState,
     Blob* blob,
     ExceptionState& exceptionState) {
   ASSERT(blob);
 
   std::unique_ptr<FileReaderLoader> loader =
       FileReaderLoader::create(FileReaderLoader::ReadAsArrayBuffer, nullptr);
-  startLoading(executionContext, *loader, *blob, exceptionState);
+  startLoading(scriptState->getExecutionContext(), *loader, *blob,
+               exceptionState);
 
   return loader->arrayBufferResult();
 }
 
-String FileReaderSync::readAsBinaryString(ExecutionContext* executionContext,
+String FileReaderSync::readAsBinaryString(ScriptState* scriptState,
                                           Blob* blob,
                                           ExceptionState& exceptionState) {
   ASSERT(blob);
 
   std::unique_ptr<FileReaderLoader> loader =
       FileReaderLoader::create(FileReaderLoader::ReadAsBinaryString, nullptr);
-  startLoading(executionContext, *loader, *blob, exceptionState);
+  startLoading(scriptState->getExecutionContext(), *loader, *blob,
+               exceptionState);
   return loader->stringResult();
 }
 
-String FileReaderSync::readAsText(ExecutionContext* executionContext,
+String FileReaderSync::readAsText(ScriptState* scriptState,
                                   Blob* blob,
                                   const String& encoding,
                                   ExceptionState& exceptionState) {
@@ -73,11 +76,12 @@
   std::unique_ptr<FileReaderLoader> loader =
       FileReaderLoader::create(FileReaderLoader::ReadAsText, nullptr);
   loader->setEncoding(encoding);
-  startLoading(executionContext, *loader, *blob, exceptionState);
+  startLoading(scriptState->getExecutionContext(), *loader, *blob,
+               exceptionState);
   return loader->stringResult();
 }
 
-String FileReaderSync::readAsDataURL(ExecutionContext* executionContext,
+String FileReaderSync::readAsDataURL(ScriptState* scriptState,
                                      Blob* blob,
                                      ExceptionState& exceptionState) {
   ASSERT(blob);
@@ -85,7 +89,8 @@
   std::unique_ptr<FileReaderLoader> loader =
       FileReaderLoader::create(FileReaderLoader::ReadAsDataURL, nullptr);
   loader->setDataType(blob->type());
-  startLoading(executionContext, *loader, *blob, exceptionState);
+  startLoading(scriptState->getExecutionContext(), *loader, *blob,
+               exceptionState);
   return loader->stringResult();
 }
 
diff --git a/third_party/WebKit/Source/core/fileapi/FileReaderSync.h b/third_party/WebKit/Source/core/fileapi/FileReaderSync.h
index ea74393b..b6dc4ca 100644
--- a/third_party/WebKit/Source/core/fileapi/FileReaderSync.h
+++ b/third_party/WebKit/Source/core/fileapi/FileReaderSync.h
@@ -42,6 +42,7 @@
 class ExceptionState;
 class ExecutionContext;
 class FileReaderLoader;
+class ScriptState;
 
 class FileReaderSync final : public GarbageCollected<FileReaderSync>,
                              public ScriptWrappable {
@@ -50,18 +51,16 @@
  public:
   static FileReaderSync* create() { return new FileReaderSync(); }
 
-  DOMArrayBuffer* readAsArrayBuffer(ExecutionContext*, Blob*, ExceptionState&);
-  String readAsBinaryString(ExecutionContext*, Blob*, ExceptionState&);
-  String readAsText(ExecutionContext* executionContext,
-                    Blob* blob,
-                    ExceptionState& ec) {
-    return readAsText(executionContext, blob, "", ec);
+  DOMArrayBuffer* readAsArrayBuffer(ScriptState*, Blob*, ExceptionState&);
+  String readAsBinaryString(ScriptState*, Blob*, ExceptionState&);
+  String readAsText(ScriptState* scriptState, Blob* blob, ExceptionState& ec) {
+    return readAsText(scriptState, blob, "", ec);
   }
-  String readAsText(ExecutionContext*,
+  String readAsText(ScriptState*,
                     Blob*,
                     const String& encoding,
                     ExceptionState&);
-  String readAsDataURL(ExecutionContext*, Blob*, ExceptionState&);
+  String readAsDataURL(ScriptState*, Blob*, ExceptionState&);
 
   DEFINE_INLINE_TRACE() {}
 
diff --git a/third_party/WebKit/Source/core/fileapi/FileReaderSync.idl b/third_party/WebKit/Source/core/fileapi/FileReaderSync.idl
index 8166be3..990bf673 100644
--- a/third_party/WebKit/Source/core/fileapi/FileReaderSync.idl
+++ b/third_party/WebKit/Source/core/fileapi/FileReaderSync.idl
@@ -34,8 +34,8 @@
     Exposed=Worker,
     Constructor,
 ] interface FileReaderSync {
-    [CallWith=ExecutionContext, RaisesException] ArrayBuffer readAsArrayBuffer(Blob blob);
-    [CallWith=ExecutionContext, RaisesException] DOMString readAsBinaryString(Blob blob);
-    [CallWith=ExecutionContext, RaisesException] DOMString readAsText(Blob blob, optional DOMString label);
-    [CallWith=ExecutionContext, RaisesException] DOMString readAsDataURL(Blob blob);
+    [CallWith=ScriptState, RaisesException] ArrayBuffer readAsArrayBuffer(Blob blob);
+    [CallWith=ScriptState, RaisesException] DOMString readAsBinaryString(Blob blob);
+    [CallWith=ScriptState, RaisesException] DOMString readAsText(Blob blob, optional DOMString label);
+    [CallWith=ScriptState, RaisesException] DOMString readAsDataURL(Blob blob);
 };
diff --git a/third_party/WebKit/Source/core/frame/FrameView.cpp b/third_party/WebKit/Source/core/frame/FrameView.cpp
index b66f20f..20aa9f4 100644
--- a/third_party/WebKit/Source/core/frame/FrameView.cpp
+++ b/third_party/WebKit/Source/core/frame/FrameView.cpp
@@ -4898,11 +4898,11 @@
 FrameView::getStyleRelatedMainThreadScrollingReasons() const {
   MainThreadScrollingReasons reasons =
       static_cast<MainThreadScrollingReasons>(0);
-  for (uint32_t reason = 1;
+  for (uint32_t reason = 0;
        reason < MainThreadScrollingReason::kMainThreadScrollingReasonCount;
        ++reason) {
     if (m_mainThreadScrollingReasonsCounter[reason] > 0) {
-      reasons |= 1 << (reason - 1);
+      reasons |= 1 << reason;
     }
   }
   return reasons;
diff --git a/third_party/WebKit/Source/core/frame/History.cpp b/third_party/WebKit/Source/core/frame/History.cpp
index d6f76e68..beaa08f 100644
--- a/third_party/WebKit/Source/core/frame/History.cpp
+++ b/third_party/WebKit/Source/core/frame/History.cpp
@@ -26,6 +26,7 @@
 #include "core/frame/History.h"
 
 #include "bindings/core/v8/ExceptionState.h"
+#include "bindings/core/v8/ScriptState.h"
 #include "core/dom/Document.h"
 #include "core/frame/LocalFrame.h"
 #include "core/loader/DocumentLoader.h"
@@ -121,20 +122,20 @@
   return state == stateInternal();
 }
 
-void History::back(ExecutionContext* context) {
-  go(context, -1);
+void History::back(ScriptState* scriptState) {
+  go(scriptState, -1);
 }
 
-void History::forward(ExecutionContext* context) {
-  go(context, 1);
+void History::forward(ScriptState* scriptState) {
+  go(scriptState, 1);
 }
 
-void History::go(ExecutionContext* context, int delta) {
+void History::go(ScriptState* scriptState, int delta) {
   if (!frame() || !frame()->loader().client())
     return;
 
   DCHECK(isMainThread());
-  Document* activeDocument = toDocument(context);
+  Document* activeDocument = toDocument(scriptState->getExecutionContext());
   if (!activeDocument)
     return;
 
diff --git a/third_party/WebKit/Source/core/frame/History.h b/third_party/WebKit/Source/core/frame/History.h
index 6a3715f..1b3db702 100644
--- a/third_party/WebKit/Source/core/frame/History.h
+++ b/third_party/WebKit/Source/core/frame/History.h
@@ -38,9 +38,9 @@
 
 class LocalFrame;
 class KURL;
-class ExecutionContext;
 class ExceptionState;
 class SecurityOrigin;
+class ScriptState;
 
 // This class corresponds to the History interface.
 class CORE_EXPORT History final : public GarbageCollectedFinalized<History>,
@@ -55,9 +55,9 @@
   unsigned length() const;
   SerializedScriptValue* state();
 
-  void back(ExecutionContext*);
-  void forward(ExecutionContext*);
-  void go(ExecutionContext*, int delta);
+  void back(ScriptState*);
+  void forward(ScriptState*);
+  void go(ScriptState*, int delta);
 
   void pushState(PassRefPtr<SerializedScriptValue> data,
                  const String& title,
diff --git a/third_party/WebKit/Source/core/frame/History.idl b/third_party/WebKit/Source/core/frame/History.idl
index 6add189..81588c2 100644
--- a/third_party/WebKit/Source/core/frame/History.idl
+++ b/third_party/WebKit/Source/core/frame/History.idl
@@ -32,9 +32,9 @@
     [Measure] attribute ScrollRestoration scrollRestoration;
     // TODO(foolip): The SerializedScriptValue type should be any.
     [CachedAttribute=stateChanged] readonly attribute SerializedScriptValue state;
-    [CallWith=ExecutionContext] void go(optional long delta = 0);
-    [CallWith=ExecutionContext] void back();
-    [CallWith=ExecutionContext] void forward();
+    [CallWith=ScriptState] void go(optional long delta = 0);
+    [CallWith=ScriptState] void back();
+    [CallWith=ScriptState] void forward();
     [RaisesException] void pushState(SerializedScriptValue data, DOMString title, optional DOMString? url = null);
     [RaisesException] void replaceState(SerializedScriptValue data, DOMString title, optional DOMString? url = null);
 };
diff --git a/third_party/WebKit/Source/core/html/FormData.cpp b/third_party/WebKit/Source/core/html/FormData.cpp
index d20d2984..a64afadf 100644
--- a/third_party/WebKit/Source/core/html/FormData.cpp
+++ b/third_party/WebKit/Source/core/html/FormData.cpp
@@ -30,6 +30,7 @@
 
 #include "core/html/FormData.h"
 
+#include "bindings/core/v8/ScriptState.h"
 #include "core/fileapi/Blob.h"
 #include "core/fileapi/File.h"
 #include "core/frame/UseCounter.h"
@@ -100,12 +101,14 @@
       new Entry(encodeAndNormalize(name), encodeAndNormalize(value)));
 }
 
-void FormData::append(ExecutionContext* context,
+void FormData::append(ScriptState* scriptState,
                       const String& name,
                       Blob* blob,
                       const String& filename) {
-  if (!blob)
-    UseCounter::count(context, UseCounter::FormDataAppendNull);
+  if (!blob) {
+    UseCounter::count(scriptState->getExecutionContext(),
+                      UseCounter::FormDataAppendNull);
+  }
   append(name, blob, filename);
 }
 
diff --git a/third_party/WebKit/Source/core/html/FormData.h b/third_party/WebKit/Source/core/html/FormData.h
index c11e86a..046cdbe 100644
--- a/third_party/WebKit/Source/core/html/FormData.h
+++ b/third_party/WebKit/Source/core/html/FormData.h
@@ -33,7 +33,6 @@
 
 #include "bindings/core/v8/FileOrUSVString.h"
 #include "bindings/core/v8/Iterable.h"
-#include "bindings/core/v8/ScriptState.h"
 #include "core/CoreExport.h"
 #include "platform/heap/Handle.h"
 #include "platform/network/EncodedFormData.h"
@@ -44,6 +43,7 @@
 
 class Blob;
 class HTMLFormElement;
+class ScriptState;
 
 // Typedef from FormData.idl:
 typedef FileOrUSVString FormDataEntryValue;
@@ -66,7 +66,7 @@
 
   // FormData IDL interface.
   void append(const String& name, const String& value);
-  void append(ExecutionContext*,
+  void append(ScriptState*,
               const String& name,
               Blob*,
               const String& filename = String());
diff --git a/third_party/WebKit/Source/core/html/FormData.idl b/third_party/WebKit/Source/core/html/FormData.idl
index 46c26fea..cba06e6 100644
--- a/third_party/WebKit/Source/core/html/FormData.idl
+++ b/third_party/WebKit/Source/core/html/FormData.idl
@@ -41,7 +41,7 @@
     LegacyInterfaceTypeChecking,
 ] interface FormData {
     void append(USVString name, USVString value);
-    [CallWith=ExecutionContext] void append(USVString name, Blob value, optional USVString filename);
+    [CallWith=ScriptState] void append(USVString name, Blob value, optional USVString filename);
     [ImplementedAs=deleteEntry] void delete(USVString name);
     FormDataEntryValue? get(USVString name);
     sequence<FormDataEntryValue> getAll(USVString name);
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLSrcsetParser.cpp b/third_party/WebKit/Source/core/html/parser/HTMLSrcsetParser.cpp
index 298834ac..b2cee22 100644
--- a/third_party/WebKit/Source/core/html/parser/HTMLSrcsetParser.cpp
+++ b/third_party/WebKit/Source/core/html/parser/HTMLSrcsetParser.cpp
@@ -107,8 +107,8 @@
                                      const CharType* position,
                                      Vector<DescriptorToken>& descriptors) {
   if (position > descriptorStart)
-    descriptors.append(DescriptorToken(descriptorStart - attributeStart,
-                                       position - descriptorStart));
+    descriptors.push_back(DescriptorToken(descriptorStart - attributeStart,
+                                          position - descriptorStart));
   descriptorStart = 0;
 }
 
@@ -337,9 +337,9 @@
     unsigned imageURLStartingPosition = imageURLStart - attributeStart;
     ASSERT(imageURLEnd > imageURLStart);
     unsigned imageURLLength = imageURLEnd - imageURLStart;
-    imageCandidates.append(ImageCandidate(attribute, imageURLStartingPosition,
-                                          imageURLLength, result,
-                                          ImageCandidate::SrcsetOrigin));
+    imageCandidates.push_back(
+        ImageCandidate(attribute, imageURLStartingPosition, imageURLLength,
+                       result, ImageCandidate::SrcsetOrigin));
     // 11. Return to the step labeled splitting loop.
   }
 }
@@ -429,7 +429,7 @@
   float prevDensity = -1.0;
   for (ImageCandidate& image : imageCandidates) {
     if (image.density() != prevDensity && (!ignoreSrc || !image.srcOrigin()))
-      deDupedImageCandidates.append(&image);
+      deDupedImageCandidates.push_back(&image);
     prevDensity = image.density();
   }
   unsigned winner = selectionLogic(deDupedImageCandidates, deviceScaleFactor);
@@ -479,7 +479,7 @@
                                           document);
 
   if (!srcAttribute.isEmpty())
-    imageCandidates.append(
+    imageCandidates.push_back(
         ImageCandidate(srcAttribute, 0, srcAttribute.length(),
                        DescriptorParsingResult(), ImageCandidate::SrcOrigin));
 
@@ -495,10 +495,10 @@
     return srcAttribute;
 
   Vector<ImageCandidate> imageCandidates;
-  imageCandidates.append(srcsetImageCandidate);
+  imageCandidates.push_back(srcsetImageCandidate);
 
   if (!srcAttribute.isEmpty())
-    imageCandidates.append(
+    imageCandidates.push_back(
         ImageCandidate(srcAttribute, 0, srcAttribute.length(),
                        DescriptorParsingResult(), ImageCandidate::SrcOrigin));
 
diff --git a/third_party/WebKit/Source/core/input/BoundaryEventDispatcher.cpp b/third_party/WebKit/Source/core/input/BoundaryEventDispatcher.cpp
index c1cd91a7..2e01b7cb 100644
--- a/third_party/WebKit/Source/core/input/BoundaryEventDispatcher.cpp
+++ b/third_party/WebKit/Source/core/input/BoundaryEventDispatcher.cpp
@@ -25,7 +25,7 @@
   // Index 0 element in the ancestors arrays will be the corresponding
   // target. So the root of their document will be their last element.
   for (Node* node = targetNode; node; node = FlatTreeTraversal::parent(*node))
-    ancestors->append(node);
+    ancestors->push_back(node);
 }
 
 void buildAncestorChainsAndFindCommonAncestors(
diff --git a/third_party/WebKit/Source/core/input/EventHandler.cpp b/third_party/WebKit/Source/core/input/EventHandler.cpp
index 3670a8ae..9c52489 100644
--- a/third_party/WebKit/Source/core/input/EventHandler.cpp
+++ b/third_party/WebKit/Source/core/input/EventHandler.cpp
@@ -1507,7 +1507,7 @@
   // work that cleans the hover state.  Because the hover state for the main
   // frame is updated by calling Document::updateHoverActiveState
   while (newHoverFrameInDocument && newHoverFrameInDocument != m_frame) {
-    newHoverFrameChain.append(newHoverFrameInDocument);
+    newHoverFrameChain.push_back(newHoverFrameInDocument);
     Frame* parentFrame = newHoverFrameInDocument->tree().parent();
     newHoverFrameInDocument = parentFrame && parentFrame->isLocalFrame()
                                   ? toLocalFrame(parentFrame)
@@ -1577,7 +1577,7 @@
   LocalFrame* enteredFrameInDocument =
       targetedEvent.hitTestResult().innerNodeFrame();
   while (enteredFrameInDocument) {
-    enteredFrameChain.append(enteredFrameInDocument);
+    enteredFrameChain.push_back(enteredFrameInDocument);
     Frame* parentFrame = enteredFrameInDocument->tree().parent();
     enteredFrameInDocument = parentFrame && parentFrame->isLocalFrame()
                                  ? toLocalFrame(parentFrame)
@@ -1603,13 +1603,13 @@
     }
 
     if (exitedFrameChain.size() > 0) {
-      exitedFrameChain.append(exitedFrameInDocument);
+      exitedFrameChain.push_back(exitedFrameInDocument);
     } else {
       LocalFrame* lastEnteredFrameInDocument =
           indexEnteredFrameChain ? enteredFrameChain[indexEnteredFrameChain - 1]
                                  : nullptr;
       if (exitedFrameInDocument != lastEnteredFrameInDocument)
-        exitedFrameChain.append(exitedFrameInDocument);
+        exitedFrameChain.push_back(exitedFrameInDocument);
       else if (nextExitedFrameInDocument && indexEnteredFrameChain)
         --indexEnteredFrameChain;
     }
diff --git a/third_party/WebKit/Source/core/input/PointerEventManager.cpp b/third_party/WebKit/Source/core/input/PointerEventManager.cpp
index f4cf8f7f..5fda7469 100644
--- a/third_party/WebKit/Source/core/input/PointerEventManager.cpp
+++ b/third_party/WebKit/Source/core/input/PointerEventManager.cpp
@@ -40,7 +40,7 @@
     for (auto& point : touchEvent.touchPoints()) {
       // TODO(nzolghadr): Need to filter out stationary points
       if (point.id() == id)
-        relatedPoints.append(point);
+        relatedPoints.push_back(point);
     }
   }
   return relatedPoints;
@@ -366,7 +366,7 @@
       touchInfo.targetFrame = touchInfo.touchNode->document().frame();
     }
 
-    touchInfos.append(touchInfo);
+    touchInfos.push_back(touchInfo);
   }
 }
 
diff --git a/third_party/WebKit/Source/core/layout/BidiRunForLine.cpp b/third_party/WebKit/Source/core/layout/BidiRunForLine.cpp
index a497cf9..eedb9151c 100644
--- a/third_party/WebKit/Source/core/layout/BidiRunForLine.cpp
+++ b/third_party/WebKit/Source/core/layout/BidiRunForLine.cpp
@@ -184,7 +184,7 @@
           runWithContext.runToReplace,
           isolatedResolver.midpointStateForIsolatedRun(
               runWithContext.runToReplace));
-      topResolver.isolatedRuns().append(runWithContext);
+      topResolver.isolatedRuns().push_back(runWithContext);
     }
   }
 }
diff --git a/third_party/WebKit/Source/core/layout/ColumnBalancer.cpp b/third_party/WebKit/Source/core/layout/ColumnBalancer.cpp
index 33b3b39..a16a4d7 100644
--- a/third_party/WebKit/Source/core/layout/ColumnBalancer.cpp
+++ b/third_party/WebKit/Source/core/layout/ColumnBalancer.cpp
@@ -292,7 +292,7 @@
         columnSet().newFragmentainerGroupsAllowed())
       return;
   }
-  m_contentRuns.append(ContentRun(endOffsetInFlowThread));
+  m_contentRuns.push_back(ContentRun(endOffsetInFlowThread));
 }
 
 unsigned InitialColumnHeightFinder::contentRunIndexWithTallestColumns() const {
diff --git a/third_party/WebKit/Source/core/layout/FlexibleBoxAlgorithm.cpp b/third_party/WebKit/Source/core/layout/FlexibleBoxAlgorithm.cpp
index ea168768..7be7bb6 100644
--- a/third_party/WebKit/Source/core/layout/FlexibleBoxAlgorithm.cpp
+++ b/third_party/WebKit/Source/core/layout/FlexibleBoxAlgorithm.cpp
@@ -78,7 +78,7 @@
             m_lineBreakLength &&
         lineHasInFlowItem)
       break;
-    lineItems.append(flexItem);
+    lineItems.push_back(flexItem);
     lineHasInFlowItem = true;
     sumFlexBaseSize += flexItem.flexBaseMarginBoxSize();
     totalFlexGrow += flexItem.box->style()->flexGrow();
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlock.cpp b/third_party/WebKit/Source/core/layout/LayoutBlock.cpp
index 2c7f1e6..9875c6b 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBlock.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBlock.cpp
@@ -1060,7 +1060,7 @@
       if (p)
         p->setChildNeedsLayout();
 
-      deadObjects.append(positionedObject);
+      deadObjects.push_back(positionedObject);
     }
   }
 
@@ -1871,7 +1871,7 @@
     const LayoutPoint& additionalOffset,
     IncludeBlockVisualOverflowOrNot includeBlockOverflows) const {
   if (!isAnonymous())  // For anonymous blocks, the children add outline rects.
-    rects.append(LayoutRect(additionalOffset, size()));
+    rects.push_back(LayoutRect(additionalOffset, size()));
 
   if (includeBlockOverflows == IncludeBlockVisualOverflow &&
       !hasOverflowClip() && !hasControlClip()) {
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
index 57a5aa1..0f6faf1 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
@@ -2436,7 +2436,7 @@
     // It's common for this rect to be entirely contained in our box, so exclude
     // that simple case.
     if (!rect.isEmpty() && (rects.isEmpty() || !rects[0].contains(rect)))
-      rects.append(rect);
+      rects.push_back(rect);
   }
 }
 
@@ -2454,7 +2454,7 @@
   // https://bugs.webkit.org/show_bug.cgi?id=46781
   LayoutRect rect(accumulatedOffset, size());
   rect.expand(collapsedMarginBoxLogicalOutsets());
-  rects.append(pixelSnappedIntRect(rect));
+  rects.push_back(pixelSnappedIntRect(rect));
   continuation()->absoluteRects(
       rects,
       accumulatedOffset -
@@ -2481,7 +2481,7 @@
   // https://bugs.webkit.org/show_bug.cgi?id=46781
   LayoutRect localRect(LayoutPoint(), size());
   localRect.expand(collapsedMarginBoxLogicalOutsets());
-  quads.append(localToAbsoluteQuad(FloatRect(localRect), mode));
+  quads.push_back(localToAbsoluteQuad(FloatRect(localRect), mode));
 }
 
 LayoutObject* LayoutBlockFlow::hoverAncestor() const {
@@ -3265,7 +3265,7 @@
     if (child->isRubyRun() || child->isRubyBase())
       return;
 
-    blocksToRemove.append(toLayoutBlockFlow(child));
+    blocksToRemove.push_back(toLayoutBlockFlow(child));
   }
 
   // If we make an object's children inline we are going to frustrate any future
@@ -4562,7 +4562,7 @@
     if (topMargin || bottomMargin) {
       LayoutRect rect(additionalOffset, size());
       rect.expandEdges(topMargin, LayoutUnit(), bottomMargin, LayoutUnit());
-      rects.append(rect);
+      rects.push_back(rect);
     }
   }
 
@@ -4578,7 +4578,7 @@
       LayoutRect rect(additionalOffset.x() + curr->x(),
                       additionalOffset.y() + top, curr->width(), bottom - top);
       if (!rect.isEmpty())
-        rects.append(rect);
+        rects.push_back(rect);
     }
   }
 
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlockFlowLine.cpp b/third_party/WebKit/Source/core/layout/LayoutBlockFlowLine.cpp
index 7ee88a8..4c53050 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBlockFlowLine.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBlockFlowLine.cpp
@@ -67,7 +67,7 @@
           text.characters16() + run.m_start, run.m_stop - run.m_start,
           run.m_box->direction(), isAfterExpansion, textJustify);
     }
-    m_runsWithExpansions.append(opportunitiesInRun);
+    m_runsWithExpansions.push_back(opportunitiesInRun);
     m_totalOpportunities += opportunitiesInRun;
   }
   void removeTrailingExpansion() {
@@ -1930,7 +1930,7 @@
         if (o->isOutOfFlowPositioned()) {
           o->containingBlock()->insertPositionedObject(box);
         } else if (o->isFloating()) {
-          layoutState.floats().append(FloatWithRect(box));
+          layoutState.floats().push_back(FloatWithRect(box));
           if (box->needsLayout()) {
             // Be sure to at least mark the first line affected by the float as
             // dirty, so that the float gets relaid out. Otherwise we'll miss
diff --git a/third_party/WebKit/Source/core/layout/LayoutBox.cpp b/third_party/WebKit/Source/core/layout/LayoutBox.cpp
index 57b0a062..68cd2c8c 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBox.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBox.cpp
@@ -700,7 +700,7 @@
 
 void LayoutBox::absoluteRects(Vector<IntRect>& rects,
                               const LayoutPoint& accumulatedOffset) const {
-  rects.append(pixelSnappedIntRect(accumulatedOffset, size()));
+  rects.push_back(pixelSnappedIntRect(accumulatedOffset, size()));
 }
 
 void LayoutBox::absoluteQuads(Vector<FloatQuad>& quads,
@@ -709,7 +709,7 @@
     flowThread->absoluteQuadsForDescendant(*this, quads, mode);
     return;
   }
-  quads.append(
+  quads.push_back(
       localToAbsoluteQuad(FloatRect(0, 0, m_frameRect.width().toFloat(),
                                     m_frameRect.height().toFloat()),
                           mode));
@@ -906,7 +906,7 @@
 void LayoutBox::addOutlineRects(Vector<LayoutRect>& rects,
                                 const LayoutPoint& additionalOffset,
                                 IncludeBlockVisualOverflowOrNot) const {
-  rects.append(LayoutRect(additionalOffset, size()));
+  rects.push_back(LayoutRect(additionalOffset, size()));
 }
 
 bool LayoutBox::canResize() const {
@@ -929,7 +929,7 @@
 void LayoutBox::computeSelfHitTestRects(Vector<LayoutRect>& rects,
                                         const LayoutPoint& layerOffset) const {
   if (!size().isEmpty())
-    rects.append(LayoutRect(layerOffset, size()));
+    rects.push_back(LayoutRect(layerOffset, size()));
 }
 
 int LayoutBox::verticalScrollbarWidth() const {
diff --git a/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp b/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp
index 80694bd..e859346c 100644
--- a/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp
@@ -963,7 +963,7 @@
       continue;
     }
 
-    allItems.append(constructFlexItem(*child, layoutType));
+    allItems.push_back(constructFlexItem(*child, layoutType));
   }
 
   const LayoutUnit lineBreakLength = mainAxisContentExtent(LayoutUnit::max());
@@ -1420,7 +1420,7 @@
         (flexSign == NegativeFlexibility &&
          flexItem.flexBaseContentSize < flexItem.hypotheticalMainContentSize)) {
       flexItem.flexedContentSize = flexItem.hypotheticalMainContentSize;
-      newInflexibleItems.append(&flexItem);
+      newInflexibleItems.push_back(&flexItem);
     }
   }
   freezeViolations(newInflexibleItems, remainingFreeSpace, totalFlexGrow,
@@ -1481,9 +1481,9 @@
 
     LayoutUnit violation = adjustedChildSize - childSize;
     if (violation > 0)
-      minViolations.append(&flexItem);
+      minViolations.push_back(&flexItem);
     else if (violation < 0)
-      maxViolations.append(&flexItem);
+      maxViolations.push_back(&flexItem);
     totalViolation += violation;
   }
 
@@ -1892,8 +1892,8 @@
 
   if (m_numberOfInFlowChildrenOnFirstLine == -1)
     m_numberOfInFlowChildrenOnFirstLine = children.size();
-  lineContexts.append(LineContext(crossAxisOffset, maxChildCrossAxisExtent,
-                                  maxAscent, std::move(children)));
+  lineContexts.push_back(LineContext(crossAxisOffset, maxChildCrossAxisExtent,
+                                     maxAscent, std::move(children)));
   crossAxisOffset += maxChildCrossAxisExtent;
 }
 
@@ -2063,7 +2063,7 @@
                                         offset);
       }
     }
-    minMarginAfterBaselines.append(minMarginAfterBaseline);
+    minMarginAfterBaselines.push_back(minMarginAfterBaseline);
   }
 
   if (style()->flexWrap() != FlexWrapReverse)
diff --git a/third_party/WebKit/Source/core/layout/LayoutFlowThread.cpp b/third_party/WebKit/Source/core/layout/LayoutFlowThread.cpp
index f6f79ba..73ddc3f6 100644
--- a/third_party/WebKit/Source/core/layout/LayoutFlowThread.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutFlowThread.cpp
@@ -138,7 +138,7 @@
     // coordinates for zero-height objects.
     fragment.inclusiveIntersect(iterator.fragmentainerInFlowThread());
     fragment.moveBy(-offsetFromFlowThread);
-    quads.append(descendant.localToAbsoluteQuad(FloatRect(fragment), mode));
+    quads.push_back(descendant.localToAbsoluteQuad(FloatRect(fragment), mode));
   }
 }
 
diff --git a/third_party/WebKit/Source/core/layout/LayoutGrid.cpp b/third_party/WebKit/Source/core/layout/LayoutGrid.cpp
index eef54fb..bd8979a 100644
--- a/third_party/WebKit/Source/core/layout/LayoutGrid.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutGrid.cpp
@@ -71,7 +71,7 @@
 
   for (const auto& row : area.rows) {
     for (const auto& column : area.columns)
-      m_grid[row][column].append(&child);
+      m_grid[row][column].push_back(&child);
   }
 
   setGridItemArea(child, area);
@@ -908,9 +908,9 @@
     }
 
     if (trackSize.isContentSized())
-      sizingData.contentSizedTracksIndex.append(i);
+      sizingData.contentSizedTracksIndex.push_back(i);
     if (trackSize.maxTrackBreadth().isFlex())
-      flexibleSizedTracksIndex.append(i);
+      flexibleSizedTracksIndex.push_back(i);
   }
 
   // 2. Resolve content-based TrackSizingFunctions.
@@ -1161,7 +1161,7 @@
     if (!trackSize.maxTrackBreadth().isFlex()) {
       leftOverSpace -= tracks[trackIndex].baseSize();
     } else {
-      flexibleTracksIndexes.append(trackIndex);
+      flexibleTracksIndexes.push_back(trackIndex);
       flexFactorSum += trackSize.maxTrackBreadth().flex();
     }
   }
@@ -1537,7 +1537,7 @@
                 direction, span, *gridItem, track, sizingData);
           } else if (!spanningItemCrossesFlexibleSizedTracks(span, direction,
                                                              sizingData)) {
-            sizingData.itemsSortedByIncreasingSpan.append(
+            sizingData.itemsSortedByIncreasingSpan.push_back(
                 GridItemWithSpan(*gridItem, span));
           }
         }
@@ -1781,11 +1781,11 @@
       if (!shouldProcessTrackForTrackSizeComputationPhase(phase, trackSize))
         continue;
 
-      sizingData.filteredTracks.append(&track);
+      sizingData.filteredTracks.push_back(&track);
 
       if (trackShouldGrowBeyondGrowthLimitsForTrackSizeComputationPhase(
               phase, trackSize))
-        sizingData.growBeyondGrowthLimitsTracks.append(&track);
+        sizingData.growBeyondGrowthLimitsTracks.push_back(&track);
     }
 
     if (sizingData.filteredTracks.isEmpty())
@@ -2127,9 +2127,9 @@
           (autoPlacementMajorAxisDirection() == ForColumns) ? area.columns
                                                             : area.rows;
       if (majorAxisPositions.isIndefinite())
-        autoMajorAxisAutoGridItems.append(child);
+        autoMajorAxisAutoGridItems.push_back(child);
       else
-        specifiedMajorAxisAutoGridItems.append(child);
+        specifiedMajorAxisAutoGridItems.push_back(child);
       continue;
     }
     grid.insert(*child, area);
@@ -2436,8 +2436,9 @@
                        : LayoutUnit();
   tracks.reserveCapacity(numPositions - 1);
   for (size_t i = 0; i < numPositions - 2; ++i)
-    tracks.append(positions[i + 1] - positions[i] - offsetBetweenTracks - gap);
-  tracks.append(positions[numPositions - 1] - positions[numPositions - 2]);
+    tracks.push_back(positions[i + 1] - positions[i] - offsetBetweenTracks -
+                     gap);
+  tracks.push_back(positions[numPositions - 1] - positions[numPositions - 2]);
 
   if (!hasCollapsedTracks)
     return tracks;
@@ -2490,7 +2491,7 @@
   for (unsigned i = 0; i < tracks.size(); ++i) {
     const GridTrackSize& trackSize = gridTrackSize(direction, i, sizingData);
     if (trackSize.hasAutoMaxTrackBreadth())
-      autoSizedTracksIndex.append(i);
+      autoSizedTracksIndex.push_back(i);
   }
 
   unsigned numberOfAutoSizedTracks = autoSizedTracksIndex.size();
@@ -2582,7 +2583,7 @@
         gridAreaLogicalPosition(area),
         LayoutSize(childGridAreaWidth, childGridAreaHeight));
     if (!gridAreaRect.contains(child->frameRect()))
-      m_gridItemsOverflowingGridArea.append(child);
+      m_gridItemsOverflowingGridArea.push_back(child);
   }
 }
 
diff --git a/third_party/WebKit/Source/core/layout/LayoutInline.cpp b/third_party/WebKit/Source/core/layout/LayoutInline.cpp
index 462ca04..586f8ad 100644
--- a/third_party/WebKit/Source/core/layout/LayoutInline.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutInline.cpp
@@ -420,7 +420,7 @@
   for (LayoutObject* o = this; o != fromBlock; o = o->parent()) {
     topMostInline = toLayoutInline(o);
     if (inlinesToClone.size() < cMaxSplitDepth)
-      inlinesToClone.append(topMostInline);
+      inlinesToClone.push_back(topMostInline);
     // Keep walking up the chain to ensure |topMostInline| is a child of
     // |fromBlock|, to avoid assertion failure when |fromBlock|'s children are
     // moved to |toBlock| below.
@@ -721,7 +721,7 @@
     IntRect intRect = enclosingIntRect(rect);
     intRect.move(m_accumulatedOffset.x().toInt(),
                  m_accumulatedOffset.y().toInt());
-    m_rects.append(intRect);
+    m_rects.push_back(intRect);
   }
 
  private:
@@ -765,7 +765,7 @@
   }
 
   void operator()(const FloatRect& rect) {
-    m_quads.append(m_geometryMap.absoluteRect(rect));
+    m_quads.push_back(m_geometryMap.absoluteRect(rect));
   }
   void operator()(const LayoutRect& rect) { operator()(FloatRect(rect)); }
 
@@ -1420,7 +1420,7 @@
   void operator()(const LayoutRect& rect) {
     LayoutRect layoutRect(rect);
     layoutRect.moveBy(m_accumulatedOffset);
-    m_rects.append(layoutRect);
+    m_rects.push_back(layoutRect);
   }
 
  private:
@@ -1502,7 +1502,7 @@
   region.bounds.setX(LayoutUnit(absPos.x() + region.bounds.x()));
   region.bounds.setY(LayoutUnit(absPos.y() + region.bounds.y()));
 
-  regions.append(region);
+  regions.push_back(region);
 }
 
 void LayoutInline::invalidateDisplayItemClients(
diff --git a/third_party/WebKit/Source/core/layout/LayoutMultiColumnSet.cpp b/third_party/WebKit/Source/core/layout/LayoutMultiColumnSet.cpp
index 6044f69..ddc5cd2b 100644
--- a/third_party/WebKit/Source/core/layout/LayoutMultiColumnSet.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutMultiColumnSet.cpp
@@ -612,7 +612,7 @@
         ruleBottom = ruleTop + ruleThickness;
       }
 
-      columnRuleBounds.append(LayoutRect(
+      columnRuleBounds.push_back(LayoutRect(
           ruleLeft, ruleTop, ruleRight - ruleLeft, ruleBottom - ruleTop));
     }
 
diff --git a/third_party/WebKit/Source/core/layout/LayoutObject.cpp b/third_party/WebKit/Source/core/layout/LayoutObject.cpp
index b5e23dc..cb6243a 100644
--- a/third_party/WebKit/Source/core/layout/LayoutObject.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutObject.cpp
@@ -2441,7 +2441,7 @@
     iterValue = &iter->value;
   for (size_t i = 0; i < ownRects.size(); i++) {
     if (!containerRect.contains(ownRects[i])) {
-      iterValue->append(ownRects[i]);
+      iterValue->push_back(ownRects[i]);
       if (iterValue->size() > maxRectsPerLayer) {
         // Just mark the entire layer instead, and switch to walking the layer
         // tree instead of the layout tree.
@@ -3130,7 +3130,7 @@
   AnnotatedRegionValue region;
   region.draggable = style()->getDraggableRegionMode() == DraggableRegionDrag;
   region.bounds = LayoutRect(absBounds);
-  regions.append(region);
+  regions.push_back(region);
 }
 
 bool LayoutObject::willRenderImage() {
diff --git a/third_party/WebKit/Source/core/layout/LayoutTable.cpp b/third_party/WebKit/Source/core/layout/LayoutTable.cpp
index a42be72..a541b24 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTable.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutTable.cpp
@@ -216,7 +216,7 @@
 
 void LayoutTable::addCaption(const LayoutTableCaption* caption) {
   ASSERT(m_captions.find(caption) == kNotFound);
-  m_captions.append(const_cast<LayoutTableCaption*>(caption));
+  m_captions.push_back(const_cast<LayoutTableCaption*>(caption));
 }
 
 void LayoutTable::removeCaption(const LayoutTableCaption* oldCaption) {
@@ -960,7 +960,7 @@
 
 void LayoutTable::appendEffectiveColumn(unsigned span) {
   unsigned newColumnIndex = m_effectiveColumns.size();
-  m_effectiveColumns.append(span);
+  m_effectiveColumns.push_back(span);
 
   // Unless the table has cell(s) with colspan that exceed the number of columns
   // afforded by the other rows in the table we can use the fast path when
@@ -1006,7 +1006,7 @@
        columnLayoutObject = columnLayoutObject->nextColumn()) {
     if (columnLayoutObject->isTableColumnGroupWithColumnChildren())
       continue;
-    m_columnLayoutObjects.append(columnLayoutObject);
+    m_columnLayoutObjects.push_back(columnLayoutObject);
   }
   m_columnLayoutObjectsValid = true;
 }
diff --git a/third_party/WebKit/Source/core/layout/LayoutTableCell.cpp b/third_party/WebKit/Source/core/layout/LayoutTableCell.cpp
index 7832d30..401dbeb 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTableCell.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutTableCell.cpp
@@ -1315,7 +1315,7 @@
     if (borderValues[i].isSameIgnoringColor(borderValue))
       return;
   }
-  borderValues.append(borderValue);
+  borderValues.push_back(borderValue);
 }
 
 void LayoutTableCell::collectBorderValues(
diff --git a/third_party/WebKit/Source/core/layout/LayoutTableSection.cpp b/third_party/WebKit/Source/core/layout/LayoutTableSection.cpp
index 603f7c35..6fb6a84f 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTableSection.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutTableSection.cpp
@@ -286,7 +286,7 @@
       ensureCols(insertionRow + r, m_cCol + 1);
       CellStruct& c = cellAt(insertionRow + r, m_cCol);
       ASSERT(cell);
-      c.cells.append(cell);
+      c.cells.push_back(cell);
       checkThatVectorIsDOMOrdered(c.cells);
       // If cells overlap then we take the slow path for painting.
       if (c.cells.size() > 1)
@@ -649,7 +649,7 @@
   for (unsigned row = 0; row < m_grid.size(); row++) {
     if (rowHasOnlySpanningCells(row))
       count++;
-    rowsCountWithOnlySpanningCells.append(count);
+    rowsCountWithOnlySpanningCells.push_back(count);
   }
 
   for (unsigned i = 0; i < rowSpanCells.size(); i++) {
@@ -896,7 +896,7 @@
               std::max(indexOfFirstStretchableRow, rowIndexBelowCell);
         } else if (cell->rowSpan() > 1) {
           DCHECK(!rowSpanCells.contains(cell));
-          rowSpanCells.append(cell);
+          rowSpanCells.push_back(cell);
         }
 
         if (cell->hasOverrideLogicalContentHeight()) {
diff --git a/third_party/WebKit/Source/core/layout/LayoutText.cpp b/third_party/WebKit/Source/core/layout/LayoutText.cpp
index 0e2a831..88a17f8 100644
--- a/third_party/WebKit/Source/core/layout/LayoutText.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutText.cpp
@@ -333,7 +333,7 @@
 void LayoutText::absoluteRects(Vector<IntRect>& rects,
                                const LayoutPoint& accumulatedOffset) const {
   for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
-    rects.append(enclosingIntRect(LayoutRect(
+    rects.push_back(enclosingIntRect(LayoutRect(
         LayoutPoint(accumulatedOffset) + box->location(), box->size())));
   }
 }
@@ -392,13 +392,13 @@
           r.setX(selectionRect.x().toFloat());
         }
       }
-      rects.append(localToAbsoluteQuad(r).enclosingBoundingBox());
+      rects.push_back(localToAbsoluteQuad(r).enclosingBoundingBox());
     } else {
       // FIXME: This code is wrong. It's converting local to absolute twice.
       // http://webkit.org/b/65722
       FloatRect rect = localQuadForTextBox(box, start, end, useSelectionHeight);
       if (!rect.isZero())
-        rects.append(localToAbsoluteQuad(rect).enclosingBoundingBox());
+        rects.push_back(localToAbsoluteQuad(rect).enclosingBoundingBox());
     }
   }
 }
@@ -449,9 +449,9 @@
         boundaries.setHeight(ellipsisRect.maxY() - boundaries.y());
     }
     if (localOrAbsolute == AbsoluteQuads)
-      quads.append(localToAbsoluteQuad(boundaries, mode));
+      quads.push_back(localToAbsoluteQuad(boundaries, mode));
     else
-      quads.append(boundaries);
+      quads.push_back(boundaries);
   }
 }
 
@@ -499,11 +499,11 @@
           r.setX(selectionRect.x());
         }
       }
-      quads.append(localToAbsoluteQuad(FloatRect(r)));
+      quads.push_back(localToAbsoluteQuad(FloatRect(r)));
     } else {
       FloatRect rect = localQuadForTextBox(box, start, end, useSelectionHeight);
       if (!rect.isZero())
-        quads.append(localToAbsoluteQuad(rect));
+        quads.push_back(localToAbsoluteQuad(rect));
     }
   }
 }
diff --git a/third_party/WebKit/Source/core/layout/LayoutTextControl.cpp b/third_party/WebKit/Source/core/layout/LayoutTextControl.cpp
index af49330..5a31b4f 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTextControl.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutTextControl.cpp
@@ -315,7 +315,7 @@
 void LayoutTextControl::addOutlineRects(Vector<LayoutRect>& rects,
                                         const LayoutPoint& additionalOffset,
                                         IncludeBlockVisualOverflowOrNot) const {
-  rects.append(LayoutRect(additionalOffset, size()));
+  rects.push_back(LayoutRect(additionalOffset, size()));
 }
 
 LayoutObject* LayoutTextControl::layoutSpecialExcludedChild(
diff --git a/third_party/WebKit/Source/core/layout/LayoutTreeAsText.cpp b/third_party/WebKit/Source/core/layout/LayoutTreeAsText.cpp
index 715f84c..3ffe71d6 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTreeAsText.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutTreeAsText.cpp
@@ -656,7 +656,7 @@
   PaintLayerStackingNodeIterator it(*node, NormalFlowChildren);
   Vector<PaintLayerStackingNode*> vector;
   while (PaintLayerStackingNode* normalFlowChild = it.next())
-    vector.append(normalFlowChild);
+    vector.push_back(normalFlowChild);
   return vector;
 }
 
diff --git a/third_party/WebKit/Source/core/layout/LayoutView.cpp b/third_party/WebKit/Source/core/layout/LayoutView.cpp
index 269ad5b..640871b 100644
--- a/third_party/WebKit/Source/core/layout/LayoutView.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutView.cpp
@@ -406,7 +406,7 @@
   // just use the viewport size (containing block) here because we want to
   // ensure this includes all children (so we can avoid walking them
   // explicitly).
-  rects.append(
+  rects.push_back(
       LayoutRect(LayoutPoint::zero(), LayoutSize(frameView()->contentsSize())));
 }
 
@@ -527,13 +527,13 @@
 
 void LayoutView::absoluteRects(Vector<IntRect>& rects,
                                const LayoutPoint& accumulatedOffset) const {
-  rects.append(
+  rects.push_back(
       pixelSnappedIntRect(accumulatedOffset, LayoutSize(layer()->size())));
 }
 
 void LayoutView::absoluteQuads(Vector<FloatQuad>& quads,
                                MapCoordinatesFlags mode) const {
-  quads.append(localToAbsoluteQuad(
+  quads.push_back(localToAbsoluteQuad(
       FloatRect(FloatPoint(), FloatSize(layer()->size())), mode));
 }
 
diff --git a/third_party/WebKit/Source/core/layout/MultiColumnFragmentainerGroup.h b/third_party/WebKit/Source/core/layout/MultiColumnFragmentainerGroup.h
index 5fdf6402..3cd5bba 100644
--- a/third_party/WebKit/Source/core/layout/MultiColumnFragmentainerGroup.h
+++ b/third_party/WebKit/Source/core/layout/MultiColumnFragmentainerGroup.h
@@ -193,7 +193,7 @@
   }
 
   void append(const MultiColumnFragmentainerGroup& group) {
-    m_groups.append(group);
+    m_groups.push_back(group);
   }
   void shrink(size_t size) { m_groups.shrink(size); }
 
diff --git a/third_party/WebKit/Source/core/layout/PaintInvalidationState.cpp b/third_party/WebKit/Source/core/layout/PaintInvalidationState.cpp
index fe434f3..bbf3b8a 100644
--- a/third_party/WebKit/Source/core/layout/PaintInvalidationState.cpp
+++ b/third_party/WebKit/Source/core/layout/PaintInvalidationState.cpp
@@ -236,8 +236,10 @@
     const LayoutObject& child) const {
   if (child.hasLayer() && toLayoutBoxModelObject(child).hasSelfPaintingLayer())
     return *toLayoutBoxModelObject(child).layer();
-  // See LayoutObject::paintingLayer() for specialty of floating objects.
-  if (child.isFloating() && !m_currentObject.isLayoutBlock())
+  // See LayoutObject::paintingLayer() for the special-cases of floating under
+  // inline and multicolumn.
+  if (child.isColumnSpanAll() ||
+      (child.isFloating() && !m_currentObject.isLayoutBlock()))
     return *child.paintingLayer();
   return m_paintingLayer;
 }
@@ -318,7 +320,7 @@
 
   switch (reason) {
     case PaintInvalidationDelayedFull:
-      m_pendingDelayedPaintInvalidations.append(&m_currentObject);
+      m_pendingDelayedPaintInvalidations.push_back(&m_currentObject);
       break;
     case PaintInvalidationSubtree:
       m_forcedSubtreeInvalidationFlags |=
diff --git a/third_party/WebKit/Source/core/layout/TableLayoutAlgorithmFixed.cpp b/third_party/WebKit/Source/core/layout/TableLayoutAlgorithmFixed.cpp
index 064ddc86..42157a4a 100644
--- a/third_party/WebKit/Source/core/layout/TableLayoutAlgorithmFixed.cpp
+++ b/third_party/WebKit/Source/core/layout/TableLayoutAlgorithmFixed.cpp
@@ -108,13 +108,13 @@
       if (currentEffectiveColumn >= nEffCols) {
         m_table->appendEffectiveColumn(span);
         nEffCols++;
-        m_width.append(Length());
+        m_width.push_back(Length());
         spanInCurrentEffectiveColumn = span;
       } else {
         if (span < m_table->spanOfEffectiveColumn(currentEffectiveColumn)) {
           m_table->splitEffectiveColumn(currentEffectiveColumn, span);
           nEffCols++;
-          m_width.append(Length());
+          m_width.push_back(Length());
         }
         spanInCurrentEffectiveColumn =
             m_table->spanOfEffectiveColumn(currentEffectiveColumn);
diff --git a/third_party/WebKit/Source/core/layout/TextAutosizer.cpp b/third_party/WebKit/Source/core/layout/TextAutosizer.cpp
index 8eb6562d..4a760ee 100644
--- a/third_party/WebKit/Source/core/layout/TextAutosizer.cpp
+++ b/third_party/WebKit/Source/core/layout/TextAutosizer.cpp
@@ -389,7 +389,7 @@
     m_blocksThatHaveBegunLayout.add(block);
 #endif
     if (Cluster* cluster = maybeCreateCluster(block))
-      m_clusterStack.append(WTF::wrapUnique(cluster));
+      m_clusterStack.push_back(WTF::wrapUnique(cluster));
   }
 }
 
@@ -403,7 +403,7 @@
   ASSERT(!m_clusterStack.isEmpty() || block->isLayoutView());
 
   if (Cluster* cluster = maybeCreateCluster(block))
-    m_clusterStack.append(WTF::wrapUnique(cluster));
+    m_clusterStack.push_back(WTF::wrapUnique(cluster));
 
   ASSERT(!m_clusterStack.isEmpty());
 
@@ -1170,7 +1170,7 @@
       // Don't free currentStyle until the end of the layout pass. This allows
       // other parts of the system to safely hold raw ComputedStyle* pointers
       // during layout, e.g. BreakingContext::m_currentStyle.
-      m_stylesRetainedDuringLayout.append(&currentStyle);
+      m_stylesRetainedDuringLayout.push_back(&currentStyle);
 
       layoutObject->setStyleInternal(style.release());
       DCHECK(!layouter || layoutObject->isDescendantOf(&layouter->root()));
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
index 57323476..e4f5b18 100644
--- a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
+++ b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
@@ -893,7 +893,7 @@
       TRACE_LAYER_INVALIDATION(layers[i].paintLayer,
                                InspectorLayerInvalidationTrackingEvent::
                                    SquashingLayerGeometryWasUpdated);
-      layersNeedingPaintInvalidation.append(layers[i].paintLayer);
+      layersNeedingPaintInvalidation.push_back(layers[i].paintLayer);
     }
     layers[i].offsetFromLayoutObject = newOffsetFromLayoutObject;
     layers[i].offsetFromLayoutObjectSet = true;
@@ -3341,7 +3341,7 @@
   } else {
     // Must invalidate before adding the squashed layer to the mapping.
     compositor()->paintInvalidationOnCompositingChange(squashedLayer);
-    m_squashedLayers.append(paintInfo);
+    m_squashedLayers.push_back(paintInfo);
   }
   squashedLayer->setGroupedMapping(
       this, PaintLayer::InvalidateLayerAndRemoveFromMapping);
@@ -3390,7 +3390,7 @@
       if (invalidateLayerIfNoPrecedingEntry(i))
         m_squashedLayers[i].paintLayer->setGroupedMapping(
             nullptr, PaintLayer::DoNotInvalidateLayerAndRemoveFromMapping);
-      layersNeedingPaintInvalidation.append(m_squashedLayers[i].paintLayer);
+      layersNeedingPaintInvalidation.push_back(m_squashedLayers[i].paintLayer);
     }
 
     m_squashedLayers.remove(nextSquashedLayerIndex,
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositingLayerAssigner.cpp b/third_party/WebKit/Source/core/layout/compositing/CompositingLayerAssigner.cpp
index ed11c2c5..7e0d81b 100644
--- a/third_party/WebKit/Source/core/layout/compositing/CompositingLayerAssigner.cpp
+++ b/third_party/WebKit/Source/core/layout/compositing/CompositingLayerAssigner.cpp
@@ -244,7 +244,7 @@
     // already-existing squashing layer.
     TRACE_LAYER_INVALIDATION(
         layer, InspectorLayerInvalidationTrackingEvent::AddedToSquashingLayer);
-    layersNeedingPaintInvalidation.append(layer);
+    layersNeedingPaintInvalidation.push_back(layer);
     m_layersChanged = true;
   } else if (compositedLayerUpdate == RemoveFromSquashingLayer) {
     if (layer->groupedMapping()) {
@@ -262,7 +262,7 @@
     TRACE_LAYER_INVALIDATION(
         layer,
         InspectorLayerInvalidationTrackingEvent::RemovedFromSquashingLayer);
-    layersNeedingPaintInvalidation.append(layer);
+    layersNeedingPaintInvalidation.push_back(layer);
     m_layersChanged = true;
 
     layer->setLostGroupedMapping(false);
@@ -295,7 +295,7 @@
           layer, compositedLayerUpdate)) {
     TRACE_LAYER_INVALIDATION(
         layer, InspectorLayerInvalidationTrackingEvent::NewCompositedLayer);
-    layersNeedingPaintInvalidation.append(layer);
+    layersNeedingPaintInvalidation.push_back(layer);
     m_layersChanged = true;
     if (ScrollingCoordinator* scrollingCoordinator =
             scrollingCoordinatorFromLayer(*layer)) {
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositingRequirementsUpdater.cpp b/third_party/WebKit/Source/core/layout/compositing/CompositingRequirementsUpdater.cpp
index ae698fe6..ffc437e5 100644
--- a/third_party/WebKit/Source/core/layout/compositing/CompositingRequirementsUpdater.cpp
+++ b/third_party/WebKit/Source/core/layout/compositing/CompositingRequirementsUpdater.cpp
@@ -38,7 +38,7 @@
 class OverlapMapContainer {
  public:
   void add(const IntRect& bounds) {
-    m_layerRects.append(bounds);
+    m_layerRects.push_back(bounds);
     m_boundingBox.unite(bounds);
   }
 
@@ -321,7 +321,7 @@
       // while we're iterating, so we have to store it for later removal.
       if (unclippedDescendant->layoutObject()->containingBlock() ==
           layer->layoutObject()) {
-        unclippedDescendantsToRemove.append(i);
+        unclippedDescendantsToRemove.push_back(i);
         continue;
       }
       if (layer->scrollsWithRespectTo(unclippedDescendant))
@@ -339,7 +339,7 @@
       // TODO(schenney): We only need to promote when the clipParent is not a
       // descendant of the ancestor scroller, which we do not check for here.
       // Hence we might be promoting needlessly.
-      unclippedDescendants.append(layer);
+      unclippedDescendants.push_back(layer);
     }
   }
 
diff --git a/third_party/WebKit/Source/core/layout/compositing/GraphicsLayerTreeBuilder.cpp b/third_party/WebKit/Source/core/layout/compositing/GraphicsLayerTreeBuilder.cpp
index 13d018c..cf28249 100644
--- a/third_party/WebKit/Source/core/layout/compositing/GraphicsLayerTreeBuilder.cpp
+++ b/third_party/WebKit/Source/core/layout/compositing/GraphicsLayerTreeBuilder.cpp
@@ -85,7 +85,7 @@
     // which needs to get parented.
     if (hasCompositedLayerMapping &&
         currentCompositedLayerMapping->foregroundLayer())
-      infoForChildren.childLayersOfEnclosingCompositedLayer->append(
+      infoForChildren.childLayersOfEnclosingCompositedLayer->push_back(
           currentCompositedLayerMapping->foregroundLayer());
   }
 
@@ -104,7 +104,7 @@
       currentCompositedLayerMapping->setSublayers(layerChildren);
 
     if (shouldAppendLayer(layer))
-      info.childLayersOfEnclosingCompositedLayer->append(
+      info.childLayersOfEnclosingCompositedLayer->push_back(
           currentCompositedLayerMapping->childForSuperlayers());
   }
 
@@ -114,7 +114,7 @@
           ->compositedLayerMapping()
           ->needsToReparentOverflowControls() &&
       layer.scrollParent()->getScrollableArea()->topmostScrollChild() == &layer)
-    info.childLayersOfEnclosingCompositedLayer->append(
+    info.childLayersOfEnclosingCompositedLayer->push_back(
         layer.scrollParent()
             ->compositedLayerMapping()
             ->detachLayerForOverflowControls(*info.enclosingCompositedLayer));
diff --git a/third_party/WebKit/Source/core/layout/line/AbstractInlineTextBox.cpp b/third_party/WebKit/Source/core/layout/line/AbstractInlineTextBox.cpp
index c726e40..84b397d 100644
--- a/third_party/WebKit/Source/core/layout/line/AbstractInlineTextBox.cpp
+++ b/third_party/WebKit/Source/core/layout/line/AbstractInlineTextBox.cpp
@@ -146,7 +146,7 @@
   while (pos >= 0 && pos < len) {
     int next = iterator->next();
     if (isWordTextBreak(iterator))
-      words.append(WordBoundaries(pos, next));
+      words.push_back(WordBoundaries(pos, next));
     pos = next;
   }
 }
diff --git a/third_party/WebKit/Source/core/layout/line/BreakingContextInlineHeaders.h b/third_party/WebKit/Source/core/layout/line/BreakingContextInlineHeaders.h
index 27c44facd..21638f79 100644
--- a/third_party/WebKit/Source/core/layout/line/BreakingContextInlineHeaders.h
+++ b/third_party/WebKit/Source/core/layout/line/BreakingContextInlineHeaders.h
@@ -479,7 +479,7 @@
     m_trailingObjects.appendObjectIfNeeded(box);
   }
   if (!containerIsInline)
-    positionedObjects.append(box);
+    positionedObjects.push_back(box);
   m_width.addUncommittedWidth(
       inlineLogicalWidthFromAncestorsIfNeeded(box).toFloat());
   // Reset prior line break context characters.
diff --git a/third_party/WebKit/Source/core/layout/line/InlineFlowBox.cpp b/third_party/WebKit/Source/core/layout/line/InlineFlowBox.cpp
index 0a19c60..29a8fad 100644
--- a/third_party/WebKit/Source/core/layout/line/InlineFlowBox.cpp
+++ b/third_party/WebKit/Source/core/layout/line/InlineFlowBox.cpp
@@ -1574,7 +1574,7 @@
   for (; leaf; leaf = leaf->nextLeafChild()) {
     minLevel = std::min(minLevel, leaf->bidiLevel());
     maxLevel = std::max(maxLevel, leaf->bidiLevel());
-    leafBoxesInLogicalOrder.append(leaf);
+    leafBoxesInLogicalOrder.push_back(leaf);
   }
 
   if (getLineLayoutItem().style()->rtlOrdering() == EOrder::Visual)
diff --git a/third_party/WebKit/Source/core/layout/line/InlineIterator.h b/third_party/WebKit/Source/core/layout/line/InlineIterator.h
index 4c17835d..c386398 100644
--- a/third_party/WebKit/Source/core/layout/line/InlineIterator.h
+++ b/third_party/WebKit/Source/core/layout/line/InlineIterator.h
@@ -661,8 +661,8 @@
   // FIXME: isolatedRuns() could be a hash of object->run and then we could
   // cheaply ASSERT here that we didn't create multiple objects for the same
   // inline.
-  resolver.isolatedRuns().append(BidiIsolatedRun(obj, pos, root, *isolatedRun,
-                                                 resolver.context()->level()));
+  resolver.isolatedRuns().push_back(BidiIsolatedRun(
+      obj, pos, root, *isolatedRun, resolver.context()->level()));
   return isolatedRun;
 }
 
diff --git a/third_party/WebKit/Source/core/layout/line/RootInlineBox.cpp b/third_party/WebKit/Source/core/layout/line/RootInlineBox.cpp
index 39637a8..c52beeb 100644
--- a/third_party/WebKit/Source/core/layout/line/RootInlineBox.cpp
+++ b/third_party/WebKit/Source/core/layout/line/RootInlineBox.cpp
@@ -613,10 +613,10 @@
                                                  ->lineHeight()
                                                  .isNegative() &&
                                              includeLeading)) {
-    usedFonts->append(box->getLineLayoutItem()
-                          .style(isFirstLineStyle())
-                          ->font()
-                          .primaryFont());
+    usedFonts->push_back(box->getLineLayoutItem()
+                             .style(isFirstLineStyle())
+                             ->font()
+                             .primaryFont());
     for (size_t i = 0; i < usedFonts->size(); ++i) {
       const FontMetrics& fontMetrics = usedFonts->at(i)->getFontMetrics();
       int usedFontAscent = fontMetrics.ascent(baselineType());
diff --git a/third_party/WebKit/Source/core/layout/line/RootInlineBox.h b/third_party/WebKit/Source/core/layout/line/RootInlineBox.h
index a962d7ff..6bfb2964 100644
--- a/third_party/WebKit/Source/core/layout/line/RootInlineBox.h
+++ b/third_party/WebKit/Source/core/layout/line/RootInlineBox.h
@@ -157,7 +157,7 @@
   void appendFloat(LayoutBox* floatingBox) {
     ASSERT(!isDirty());
     if (m_floats)
-      m_floats->append(floatingBox);
+      m_floats->push_back(floatingBox);
     else
       m_floats = WTF::wrapUnique(new Vector<LayoutBox*>(1, floatingBox));
   }
diff --git a/third_party/WebKit/Source/core/layout/line/TrailingObjects.h b/third_party/WebKit/Source/core/layout/line/TrailingObjects.h
index 5167b91..2556440 100644
--- a/third_party/WebKit/Source/core/layout/line/TrailingObjects.h
+++ b/third_party/WebKit/Source/core/layout/line/TrailingObjects.h
@@ -82,7 +82,7 @@
 
   void appendObjectIfNeeded(LineLayoutItem object) {
     if (m_whitespace)
-      m_objects.append(object);
+      m_objects.push_back(object);
   }
 
   enum CollapseFirstSpaceOrNot { DoNotCollapseFirstSpace, CollapseFirstSpace };
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.cc b/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.cc
index 3dafd316..f5a96925 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.cc
@@ -52,8 +52,8 @@
     const NGLogicalOffset& child_offset) {
   DCHECK_EQ(type_, NGPhysicalFragment::kFragmentBox)
       << "Only box fragments can have children";
-  children_.append(child->PhysicalFragment());
-  offsets_.append(child_offset);
+  children_.push_back(child->PhysicalFragment());
+  offsets_.push_back(child_offset);
   // Collect child's out of flow descendants.
   const NGPhysicalFragment* physical_fragment = child->PhysicalFragment();
   const Vector<NGStaticPosition>& oof_positions =
@@ -62,7 +62,7 @@
   for (auto& oof_node : physical_fragment->OutOfFlowDescendants()) {
     NGStaticPosition oof_position = oof_positions[oof_index++];
     out_of_flow_descendant_candidates_.add(oof_node);
-    out_of_flow_candidate_placements_.append(
+    out_of_flow_candidate_placements_.push_back(
         OutOfFlowPlacement{child_offset, oof_position});
   }
   return *this;
@@ -74,7 +74,7 @@
   out_of_flow_descendant_candidates_.add(child);
   NGStaticPosition child_position =
       NGStaticPosition::Create(writing_mode_, direction_, NGPhysicalOffset());
-  out_of_flow_candidate_placements_.append(
+  out_of_flow_candidate_placements_.push_back(
       OutOfFlowPlacement{child_offset, child_position});
   return *this;
 }
@@ -103,7 +103,7 @@
     builder_relative_position.offset =
         child_offset + oof_placement.descendant_position.offset;
     descendants->add(oof_node);
-    descendant_positions->append(builder_relative_position);
+    descendant_positions->push_back(builder_relative_position);
   }
   out_of_flow_descendant_candidates_.clear();
   out_of_flow_candidate_placements_.clear();
@@ -113,7 +113,7 @@
     NGBlockNode* descendant,
     const NGStaticPosition& position) {
   out_of_flow_descendants_.add(descendant);
-  out_of_flow_positions_.append(position);
+  out_of_flow_positions_.push_back(position);
   return *this;
 }
 
@@ -144,7 +144,7 @@
     NGPhysicalFragment* child = children_[i].get();
     child->SetOffset(offsets_[i].ConvertToPhysical(
         writing_mode_, direction_, physical_size, child->Size()));
-    children.append(child);
+    children.push_back(child);
   }
   return new NGPhysicalBoxFragment(
       physical_size, overflow_.ConvertToPhysical(writing_mode_), children,
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_inline_node.cc b/third_party/WebKit/Source/core/layout/ng/ng_inline_node.cc
index 875f52a..fdd370d 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_inline_node.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_inline_node.cc
@@ -208,7 +208,7 @@
     CachingWordShapeIterator iterator(shape_cache, item_run, &item_font);
     RefPtr<const ShapeResult> word_result;
     while (iterator.next(&word_result)) {
-      item.shape_results_.append(word_result.get());
+      item.shape_results_.push_back(word_result.get());
     };
   }
 }
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_inline_node_test.cc b/third_party/WebKit/Source/core/layout/ng/ng_inline_node_test.cc
index 8769b77..e2e98287 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_inline_node_test.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_inline_node_test.cc
@@ -30,13 +30,13 @@
   void Append(const String& text, const ComputedStyle* style = nullptr) {
     unsigned start = text_content_.length();
     text_content_.append(text);
-    items_.append(NGLayoutInlineItem(start, start + text.length(), style));
+    items_.push_back(NGLayoutInlineItem(start, start + text.length(), style));
   }
 
   void Append(UChar character) {
     text_content_.append(character);
     unsigned end = text_content_.length();
-    items_.append(NGLayoutInlineItem(end - 1, end, nullptr));
+    items_.push_back(NGLayoutInlineItem(end - 1, end, nullptr));
     is_bidi_enabled_ = true;
   }
 
@@ -72,7 +72,7 @@
     line_builder.CreateFragments(&fragment_builder);
     NGPhysicalBoxFragment* fragment = fragment_builder.ToBoxFragment();
     for (const NGPhysicalFragment* child : fragment->Children()) {
-      fragments_out->append(toNGPhysicalTextFragment(child));
+      fragments_out->push_back(toNGPhysicalTextFragment(child));
     }
   }
 
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_layout_coordinator.cc b/third_party/WebKit/Source/core/layout/ng/ng_layout_coordinator.cc
index 977f1c7..6efda39 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_layout_coordinator.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_layout_coordinator.cc
@@ -11,7 +11,7 @@
 
 NGLayoutCoordinator::NGLayoutCoordinator(NGLayoutInputNode* input_node,
                                          NGConstraintSpace* constraint_space) {
-  layout_algorithms_.append(
+  layout_algorithms_.push_back(
       NGLayoutInputNode::AlgorithmForInputNode(input_node, constraint_space));
 }
 
@@ -38,7 +38,7 @@
       fragment_ = fragment;
       return false;
     case kChildAlgorithmRequired:
-      layout_algorithms_.append(child_algorithm);
+      layout_algorithms_.push_back(child_algorithm);
       return false;
   }
 
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_layout_inline_items_builder.cc b/third_party/WebKit/Source/core/layout/ng/ng_layout_inline_items_builder.cc
index 1ac3a1d..3a9ee9b 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_layout_inline_items_builder.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_layout_inline_items_builder.cc
@@ -99,7 +99,7 @@
                                         const ComputedStyle* style) {
   if (string.isEmpty()) {
     unsigned offset = text_.length();
-    items_->append(NGLayoutInlineItem(offset, offset, style));
+    items_->push_back(NGLayoutInlineItem(offset, offset, style));
     return;
   }
 
@@ -149,7 +149,7 @@
     }
   }
 
-  items_->append(NGLayoutInlineItem(start_offset, text_.length(), style));
+  items_->push_back(NGLayoutInlineItem(start_offset, text_.length(), style));
 }
 
 void NGLayoutInlineItemsBuilder::Append(UChar character) {
@@ -166,7 +166,7 @@
 
   text_.append(character);
   unsigned end_offset = text_.length();
-  items_->append(NGLayoutInlineItem(end_offset - 1, end_offset, nullptr));
+  items_->push_back(NGLayoutInlineItem(end_offset - 1, end_offset, nullptr));
 }
 
 void NGLayoutInlineItemsBuilder::ProcessPendingNewline(
@@ -252,7 +252,7 @@
 
 void NGLayoutInlineItemsBuilder::Enter(LayoutObject* node,
                                        UChar character_to_exit) {
-  exits_.append(OnExitNode{node, character_to_exit});
+  exits_.push_back(OnExitNode{node, character_to_exit});
   has_bidi_controls_ = true;
 }
 
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_layout_opportunity_iterator.cc b/third_party/WebKit/Source/core/layout/ng/ng_layout_opportunity_iterator.cc
index 8d377ad..869deda 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_layout_opportunity_iterator.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_layout_opportunity_iterator.cc
@@ -16,7 +16,7 @@
   if (!node)
     return;
   if (node->IsLeafNode())
-    opportunities.append(node->opportunity);
+    opportunities.push_back(node->opportunity);
   CollectAllOpportunities(node->left, opportunities);
   CollectAllOpportunities(node->bottom, opportunities);
   CollectAllOpportunities(node->right, opportunities);
@@ -176,7 +176,7 @@
   NGLayoutOpportunity top_layout_opp =
       GetTopSpace(node->opportunity, exclusion->rect);
   if (!top_layout_opp.IsEmpty())
-    opportunities.append(top_layout_opp);
+    opportunities.push_back(top_layout_opp);
 
   node->exclusion = exclusion;
 }
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_line_builder.cc b/third_party/WebKit/Source/core/layout/ng/ng_line_builder.cc
index 4072fc23..e1999af 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_line_builder.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_line_builder.cc
@@ -29,7 +29,8 @@
                         unsigned end_index,
                         LayoutUnit inline_size) {
   DCHECK_LT(start_index, end_index);
-  line_item_chunks_.append(LineItemChunk{start_index, end_index, inline_size});
+  line_item_chunks_.push_back(
+      LineItemChunk{start_index, end_index, inline_size});
 }
 
 void NGLineBuilder::CreateLine() {
@@ -61,8 +62,8 @@
         text_builder.ToTextFragment(inline_box_, line_item_chunk.start_index,
                                     line_item_chunk.end_index));
 
-    fragments_.append(text_fragment);
-    offsets_.append(NGLogicalOffset(inline_offset, content_size_));
+    fragments_.push_back(text_fragment);
+    offsets_.push_back(NGLogicalOffset(inline_offset, content_size_));
     inline_offset += line_item_chunk.inline_size;
   }
   DCHECK_EQ(fragments_.size(), offsets_.size());
@@ -95,7 +96,7 @@
   Vector<UBiDiLevel, 32> levels;
   levels.reserveInitialCapacity(line_item_chunks_.size());
   for (const auto& chunk : line_item_chunks_)
-    levels.append(inline_box_->Items()[chunk.start_index].BidiLevel());
+    levels.push_back(inline_box_->Items()[chunk.start_index].BidiLevel());
   Vector<int32_t, 32> indicies_in_visual_order(line_item_chunks_.size());
   NGBidiParagraph::IndiciesInVisualOrder(levels, &indicies_in_visual_order);
 
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_units.cc b/third_party/WebKit/Source/core/layout/ng/ng_units.cc
index 4db0bc8..5ca4d0d2 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_units.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_units.cc
@@ -258,7 +258,7 @@
 }
 
 void NGExclusions::Add(const NGExclusion& exclusion) {
-  storage.append(WTF::makeUnique<NGExclusion>(exclusion));
+  storage.push_back(WTF::makeUnique<NGExclusion>(exclusion));
   if (exclusion.type == NGExclusion::kFloatLeft) {
     last_left_float = storage.rbegin()->get();
   } else if (exclusion.type == NGExclusion::kFloatRight) {
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGContainer.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGContainer.cpp
index e5839cc3..9cd0ef2 100644
--- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGContainer.cpp
+++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGContainer.cpp
@@ -170,7 +170,7 @@
     Vector<LayoutRect>& rects,
     const LayoutPoint&,
     IncludeBlockVisualOverflowOrNot) const {
-  rects.append(LayoutRect(visualRectInLocalSVGCoordinates()));
+  rects.push_back(LayoutRect(visualRectInLocalSVGCoordinates()));
 }
 
 void LayoutSVGContainer::updateCachedBoundaries() {
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGImage.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGImage.cpp
index ccd206be..44164342 100644
--- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGImage.cpp
+++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGImage.cpp
@@ -206,7 +206,7 @@
                                      IncludeBlockVisualOverflowOrNot) const {
   // this is called from paint() after the localTransform has already been
   // applied
-  rects.append(LayoutRect(visualRectInLocalSVGCoordinates()));
+  rects.push_back(LayoutRect(visualRectInLocalSVGCoordinates()));
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGInline.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGInline.cpp
index 532d84f0..4caae65 100644
--- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGInline.cpp
+++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGInline.cpp
@@ -107,7 +107,7 @@
 
   FloatRect textBoundingBox = textRoot->strokeBoundingBox();
   for (InlineFlowBox* box = firstLineBox(); box; box = box->nextLineBox()) {
-    quads.append(
+    quads.push_back(
         localToAbsoluteQuad(FloatRect(textBoundingBox.x() + box->x().toFloat(),
                                       textBoundingBox.y() + box->y().toFloat(),
                                       box->logicalWidth().toFloat(),
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGInlineText.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGInlineText.cpp
index 1158e20..5b171941 100644
--- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGInlineText.cpp
+++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGInlineText.cpp
@@ -309,7 +309,7 @@
     bool currentCharacterIsWhiteSpace = run[characterIndex] == ' ';
     if (!preserveWhiteSpace && lastCharacterWasWhiteSpace &&
         currentCharacterIsWhiteSpace) {
-      m_metrics.append(SVGTextMetrics(SVGTextMetrics::SkippedSpaceMetrics));
+      m_metrics.push_back(SVGTextMetrics(SVGTextMetrics::SkippedSpaceMetrics));
       characterIndex++;
       continue;
     }
@@ -317,7 +317,7 @@
     unsigned length = isValidSurrogatePair(run, characterIndex) ? 2 : 1;
     float width = charRanges[characterIndex].width() / m_scalingFactor;
 
-    m_metrics.append(SVGTextMetrics(length, width, cachedFontHeight));
+    m_metrics.push_back(SVGTextMetrics(length, width, cachedFontHeight));
 
     lastCharacterWasWhiteSpace = currentCharacterIsWhiteSpace;
     characterIndex += length;
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGModelObject.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGModelObject.cpp
index e7bd6bf9..201d32b 100644
--- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGModelObject.cpp
+++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGModelObject.cpp
@@ -80,12 +80,12 @@
     const LayoutPoint& accumulatedOffset) const {
   IntRect rect = enclosingIntRect(strokeBoundingBox());
   rect.moveBy(roundedIntPoint(accumulatedOffset));
-  rects.append(rect);
+  rects.push_back(rect);
 }
 
 void LayoutSVGModelObject::absoluteQuads(Vector<FloatQuad>& quads,
                                          MapCoordinatesFlags mode) const {
-  quads.append(localToAbsoluteQuad(strokeBoundingBox(), mode));
+  quads.push_back(localToAbsoluteQuad(strokeBoundingBox(), mode));
 }
 
 FloatRect LayoutSVGModelObject::localBoundingBoxRectForAccessibility() const {
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGShape.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGShape.cpp
index e523e35d..cb8752d 100644
--- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGShape.cpp
+++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGShape.cpp
@@ -246,7 +246,7 @@
 void LayoutSVGShape::addOutlineRects(Vector<LayoutRect>& rects,
                                      const LayoutPoint&,
                                      IncludeBlockVisualOverflowOrNot) const {
-  rects.append(LayoutRect(visualRectInLocalSVGCoordinates()));
+  rects.push_back(LayoutRect(visualRectInLocalSVGCoordinates()));
 }
 
 bool LayoutSVGShape::nodeAtFloatPoint(HitTestResult& result,
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGText.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGText.cpp
index d0026cc..f732e1d8 100644
--- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGText.cpp
+++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGText.cpp
@@ -98,7 +98,7 @@
   for (LayoutObject* descendant = textRoot.firstChild(); descendant;
        descendant = descendant->nextInPreOrder(&textRoot)) {
     if (descendant->isSVGInlineText())
-      descendantTextNodes.append(toLayoutSVGInlineText(descendant));
+      descendantTextNodes.push_back(toLayoutSVGInlineText(descendant));
   }
 }
 
@@ -346,7 +346,7 @@
 
 void LayoutSVGText::absoluteQuads(Vector<FloatQuad>& quads,
                                   MapCoordinatesFlags mode) const {
-  quads.append(localToAbsoluteQuad(strokeBoundingBox(), mode));
+  quads.push_back(localToAbsoluteQuad(strokeBoundingBox(), mode));
 }
 
 void LayoutSVGText::paint(const PaintInfo& paintInfo,
@@ -387,7 +387,7 @@
 void LayoutSVGText::addOutlineRects(Vector<LayoutRect>& rects,
                                     const LayoutPoint&,
                                     IncludeBlockVisualOverflowOrNot) const {
-  rects.append(LayoutRect(objectBoundingBox()));
+  rects.push_back(LayoutRect(objectBoundingBox()));
 }
 
 bool LayoutSVGText::isObjectBoundingBoxValid() const {
diff --git a/third_party/WebKit/Source/core/layout/svg/SVGLayoutSupport.cpp b/third_party/WebKit/Source/core/layout/svg/SVGLayoutSupport.cpp
index f3d53286..97111d8c 100644
--- a/third_party/WebKit/Source/core/layout/svg/SVGLayoutSupport.cpp
+++ b/third_party/WebKit/Source/core/layout/svg/SVGLayoutSupport.cpp
@@ -441,7 +441,7 @@
     const SVGLengthContext& lengthContext) {
   DashArray dashArray;
   for (const Length& dashLength : svgDashArray.vector())
-    dashArray.append(lengthContext.valueForLength(dashLength, style));
+    dashArray.push_back(lengthContext.valueForLength(dashLength, style));
   return dashArray;
 }
 
@@ -575,7 +575,7 @@
       float distance = distanceToChildLayoutObject(child, point);
       if (distance > closestText.candidateDistance)
         continue;
-      candidates.append(SearchCandidate(child, distance));
+      candidates.push_back(SearchCandidate(child, distance));
     }
   }
 
diff --git a/third_party/WebKit/Source/core/layout/svg/SVGMarkerData.h b/third_party/WebKit/Source/core/layout/svg/SVGMarkerData.h
index 4dcb7005..cba98b34 100644
--- a/third_party/WebKit/Source/core/layout/svg/SVGMarkerData.h
+++ b/third_party/WebKit/Source/core/layout/svg/SVGMarkerData.h
@@ -56,7 +56,7 @@
   }
 
   void pathIsDone() {
-    m_positions.append(
+    m_positions.push_back(
         MarkerPosition(EndMarker, m_origin, currentAngle(EndMarker)));
   }
 
@@ -121,7 +121,7 @@
     // Record the marker for the previous element.
     if (m_elementIndex > 0) {
       SVGMarkerType markerType = m_elementIndex == 1 ? StartMarker : MidMarker;
-      m_positions.append(
+      m_positions.push_back(
           MarkerPosition(markerType, m_origin, currentAngle(markerType)));
     }
 
diff --git a/third_party/WebKit/Source/core/layout/svg/SVGTextLayoutAttributesBuilder.cpp b/third_party/WebKit/Source/core/layout/svg/SVGTextLayoutAttributesBuilder.cpp
index 0339958..6a8bab4a 100644
--- a/third_party/WebKit/Source/core/layout/svg/SVGTextLayoutAttributesBuilder.cpp
+++ b/third_party/WebKit/Source/core/layout/svg/SVGTextLayoutAttributesBuilder.cpp
@@ -117,7 +117,7 @@
       positioningElementFromLayoutObject(start);
   unsigned atPosition = m_textPositions.size();
   if (element)
-    m_textPositions.append(TextPosition(element, m_characterCount));
+    m_textPositions.push_back(TextPosition(element, m_characterCount));
 
   for (LayoutObject* child = start.slowFirstChild(); child;
        child = child->nextSibling()) {
diff --git a/third_party/WebKit/Source/core/layout/svg/SVGTextLayoutEngine.cpp b/third_party/WebKit/Source/core/layout/svg/SVGTextLayoutEngine.cpp
index c5d87328..a66bd0b 100644
--- a/third_party/WebKit/Source/core/layout/svg/SVGTextLayoutEngine.cpp
+++ b/third_party/WebKit/Source/core/layout/svg/SVGTextLayoutEngine.cpp
@@ -155,7 +155,7 @@
   // Figure out fragment metrics.
   computeCurrentFragmentMetrics(textBox);
 
-  textBox->textFragments().append(m_currentTextFragment);
+  textBox->textFragments().push_back(m_currentTextFragment);
   m_currentTextFragment = SVGTextFragment();
 }
 
@@ -237,7 +237,7 @@
   if (m_inPathLayout)
     return;
 
-  m_lineLayoutBoxes.append(textBox);
+  m_lineLayoutBoxes.push_back(textBox);
 }
 
 static bool definesTextLengthWithSpacing(const InlineFlowBox* start) {
diff --git a/third_party/WebKit/Source/core/layout/svg/SVGTextQuery.cpp b/third_party/WebKit/Source/core/layout/svg/SVGTextQuery.cpp
index 5501541..17b606e 100644
--- a/third_party/WebKit/Source/core/layout/svg/SVGTextQuery.cpp
+++ b/third_party/WebKit/Source/core/layout/svg/SVGTextQuery.cpp
@@ -95,7 +95,7 @@
     }
 
     if (child->isSVGInlineTextBox())
-      textBoxes.append(toSVGInlineTextBox(child));
+      textBoxes.push_back(toSVGInlineTextBox(child));
   }
 }
 
@@ -140,7 +140,7 @@
   textBoxes.shrink(0);
   for (InlineTextBox* textBox = textLineLayout.firstTextBox(); textBox;
        textBox = textBox->nextTextBox())
-    textBoxes.append(toSVGInlineTextBox(textBox));
+    textBoxes.push_back(toSVGInlineTextBox(textBox));
   std::sort(textBoxes.begin(), textBoxes.end(), InlineTextBox::compareByStart);
 }
 
diff --git a/third_party/WebKit/Source/core/loader/DocumentLoader.cpp b/third_party/WebKit/Source/core/loader/DocumentLoader.cpp
index b9ad383..a0fa9d4 100644
--- a/third_party/WebKit/Source/core/loader/DocumentLoader.cpp
+++ b/third_party/WebKit/Source/core/loader/DocumentLoader.cpp
@@ -620,7 +620,7 @@
 }
 
 void DocumentLoader::appendRedirect(const KURL& url) {
-  m_redirectChain.append(url);
+  m_redirectChain.push_back(url);
 }
 
 void DocumentLoader::detachFromFrame() {
diff --git a/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp b/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
index 61c2753..c0ccedf 100644
--- a/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
+++ b/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
@@ -565,7 +565,7 @@
     if (activityLogger) {
       Vector<String> argv;
       argv.push_back(Resource::resourceTypeToString(type, fetchInitiatorName));
-      argv.append(request.url());
+      argv.push_back(request.url());
       activityLogger->logEvent("blinkRequestResource", argv.size(),
                                argv.data());
     }
diff --git a/third_party/WebKit/Source/core/loader/FrameLoader.cpp b/third_party/WebKit/Source/core/loader/FrameLoader.cpp
index dafe916..aa2836e1 100644
--- a/third_party/WebKit/Source/core/loader/FrameLoader.cpp
+++ b/third_party/WebKit/Source/core/loader/FrameLoader.cpp
@@ -1549,13 +1549,13 @@
   // Store all references to each subframe in advance since beforeunload's event
   // handler may modify frame
   HeapVector<Member<LocalFrame>> targetFrames;
-  targetFrames.append(m_frame);
+  targetFrames.push_back(m_frame);
   for (Frame* child = m_frame->tree().firstChild(); child;
        child = child->tree().traverseNext(m_frame)) {
     // FIXME: There is not yet any way to dispatch events to out-of-process
     // frames.
     if (child->isLocalFrame())
-      targetFrames.append(toLocalFrame(child));
+      targetFrames.push_back(toLocalFrame(child));
   }
 
   bool shouldClose = false;
diff --git a/third_party/WebKit/Source/core/observer/ResizeObserver.cpp b/third_party/WebKit/Source/core/observer/ResizeObserver.cpp
index 3a81c67..f64cd528 100644
--- a/third_party/WebKit/Source/core/observer/ResizeObserver.cpp
+++ b/third_party/WebKit/Source/core/observer/ResizeObserver.cpp
@@ -74,7 +74,7 @@
       continue;
     auto depth = observation->targetDepth();
     if (depth > deeperThan) {
-      m_activeObservations.append(*observation);
+      m_activeObservations.push_back(*observation);
       minObservedDepth = std::min(minObservedDepth, depth);
     } else {
       m_skippedObservations = true;
@@ -98,7 +98,7 @@
     observation->setObservationSize(size);
     auto entry = new ResizeObserverEntry(observation->target(),
                                          LayoutRect(location, size));
-    entries.append(entry);
+    entries.push_back(entry);
   }
   m_callback->handleEvent(entries, this);
   clearObservations();
diff --git a/third_party/WebKit/Source/core/origin_trials/OriginTrialContext.cpp b/third_party/WebKit/Source/core/origin_trials/OriginTrialContext.cpp
index 4d27565..3873ac7 100644
--- a/third_party/WebKit/Source/core/origin_trials/OriginTrialContext.cpp
+++ b/third_party/WebKit/Source/core/origin_trials/OriginTrialContext.cpp
@@ -117,7 +117,7 @@
   while (pos < len) {
     String token = extractTokenOrQuotedString(headerValue, pos);
     if (!token.isEmpty())
-      tokens->append(token);
+      tokens->push_back(token);
     // Make sure tokens are comma-separated.
     if (pos < len && headerValue[pos++] != ',')
       return nullptr;
@@ -155,7 +155,7 @@
 
 void OriginTrialContext::addToken(const String& token) {
   if (!token.isEmpty()) {
-    m_tokens.append(token);
+    m_tokens.push_back(token);
     validateToken(token);
   }
   initializePendingFeatures();
@@ -164,7 +164,7 @@
 void OriginTrialContext::addTokens(const Vector<String>& tokens) {
   for (const String& token : tokens) {
     if (!token.isEmpty()) {
-      m_tokens.append(token);
+      m_tokens.push_back(token);
       validateToken(token);
     }
   }
diff --git a/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp b/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp
index 91d5b6c..3173b5d 100644
--- a/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp
+++ b/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp
@@ -578,7 +578,7 @@
           *compositedLayer->layoutObject(), rect);
       rect.move(-graphicsLayer->offsetFromLayoutObject());
 
-      glRects->append(rect);
+      glRects->push_back(rect);
     }
   }
 
diff --git a/third_party/WebKit/Source/core/paint/BoxBorderPainter.cpp b/third_party/WebKit/Source/core/paint/BoxBorderPainter.cpp
index c490280..27d7632 100644
--- a/third_party/WebKit/Source/core/paint/BoxBorderPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/BoxBorderPainter.cpp
@@ -409,7 +409,7 @@
       BoxSide side = static_cast<BoxSide>(i);
 
       if (includesEdge(borderPainter.m_visibleEdgeSet, side))
-        sortedSides.append(side);
+        sortedSides.push_back(side);
     }
     DCHECK(!sortedSides.isEmpty());
 
@@ -459,13 +459,13 @@
       DCHECK_GT(edgeAlpha, 0u);
       DCHECK_GE(edgeAlpha, currentAlpha);
       if (edgeAlpha != currentAlpha) {
-        opacityGroups.append(OpacityGroup(edgeAlpha));
+        opacityGroups.push_back(OpacityGroup(edgeAlpha));
         currentAlpha = edgeAlpha;
       }
 
       DCHECK(!opacityGroups.isEmpty());
       OpacityGroup& currentGroup = opacityGroups.back();
-      currentGroup.sides.append(side);
+      currentGroup.sides.push_back(side);
       currentGroup.edgeFlags |= edgeFlagForSide(side);
     }
 
@@ -1005,8 +1005,8 @@
         }
 
         DashArray lineDash;
-        lineDash.append(dashLength);
-        lineDash.append(gapLength);
+        lineDash.push_back(dashLength);
+        lineDash.push_back(gapLength);
         graphicsContext.setLineDash(lineDash, dashLength);
       }
 
diff --git a/third_party/WebKit/Source/core/paint/BoxClipper.cpp b/third_party/WebKit/Source/core/paint/BoxClipper.cpp
index 5d533caa0..17ca2c8 100644
--- a/third_party/WebKit/Source/core/paint/BoxClipper.cpp
+++ b/third_party/WebKit/Source/core/paint/BoxClipper.cpp
@@ -89,7 +89,7 @@
     m_clipType = m_paintInfo.displayItemTypeForClipping();
     Vector<FloatRoundedRect> roundedRects;
     if (hasBorderRadius)
-      roundedRects.append(clipRoundedRect);
+      roundedRects.push_back(clipRoundedRect);
     m_paintInfo.context.getPaintController().createAndAppend<ClipDisplayItem>(
         m_box, m_clipType, pixelSnappedIntRect(clipRect), roundedRects);
   }
diff --git a/third_party/WebKit/Source/core/paint/BoxPainter.cpp b/third_party/WebKit/Source/core/paint/BoxPainter.cpp
index a58f9ca8..fd646a7 100644
--- a/third_party/WebKit/Source/core/paint/BoxPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/BoxPainter.cpp
@@ -271,7 +271,7 @@
   bool isNonAssociative = false;
   for (auto currentLayer = &fillLayer; currentLayer;
        currentLayer = currentLayer->next()) {
-    reversedPaintList.append(currentLayer);
+    reversedPaintList.push_back(currentLayer);
     // Stop traversal when an opaque layer is encountered.
     // FIXME : It would be possible for the following occlusion culling test to
     // be more aggressive on layers with no repeat by testing whether the image
diff --git a/third_party/WebKit/Source/core/paint/FilterEffectBuilder.cpp b/third_party/WebKit/Source/core/paint/FilterEffectBuilder.cpp
index d9c56633..7c862d8 100644
--- a/third_party/WebKit/Source/core/paint/FilterEffectBuilder.cpp
+++ b/third_party/WebKit/Source/core/paint/FilterEffectBuilder.cpp
@@ -175,7 +175,7 @@
       }
       case FilterOperation::SATURATE: {
         Vector<float> inputParameters;
-        inputParameters.append(clampTo<float>(
+        inputParameters.push_back(clampTo<float>(
             toBasicColorMatrixFilterOperation(filterOperation)->amount()));
         effect = FEColorMatrix::create(
             parentFilter, FECOLORMATRIX_TYPE_SATURATE, inputParameters);
@@ -183,7 +183,7 @@
       }
       case FilterOperation::HUE_ROTATE: {
         Vector<float> inputParameters;
-        inputParameters.append(clampTo<float>(
+        inputParameters.push_back(clampTo<float>(
             toBasicColorMatrixFilterOperation(filterOperation)->amount()));
         effect = FEColorMatrix::create(
             parentFilter, FECOLORMATRIX_TYPE_HUEROTATE, inputParameters);
@@ -195,9 +195,9 @@
         ComponentTransferFunction transferFunction;
         transferFunction.type = FECOMPONENTTRANSFER_TYPE_TABLE;
         Vector<float> transferParameters;
-        transferParameters.append(
+        transferParameters.push_back(
             clampTo<float>(componentTransferOperation->amount()));
-        transferParameters.append(
+        transferParameters.push_back(
             clampTo<float>(1 - componentTransferOperation->amount()));
         transferFunction.tableValues = transferParameters;
 
@@ -211,8 +211,8 @@
         ComponentTransferFunction transferFunction;
         transferFunction.type = FECOMPONENTTRANSFER_TYPE_TABLE;
         Vector<float> transferParameters;
-        transferParameters.append(0);
-        transferParameters.append(clampTo<float>(
+        transferParameters.push_back(0);
+        transferParameters.push_back(clampTo<float>(
             toBasicComponentTransferFilterOperation(filterOperation)
                 ->amount()));
         transferFunction.tableValues = transferParameters;
@@ -282,7 +282,7 @@
         // subregions.
         effect->setClipsToBounds(false);
         effect->setOperatingColorSpace(ColorSpaceDeviceRGB);
-        effect->inputEffects().append(previousEffect);
+        effect->inputEffects().push_back(previousEffect);
       }
       if (previousEffect->originTainted())
         effect->setOriginTainted();
diff --git a/third_party/WebKit/Source/core/paint/GridPainter.cpp b/third_party/WebKit/Source/core/paint/GridPainter.cpp
index 2df637c..fb57d1d3 100644
--- a/third_party/WebKit/Source/core/paint/GridPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/GridPainter.cpp
@@ -84,14 +84,14 @@
       const Vector<LayoutBox*, 1>& children =
           m_layoutGrid.gridCell(row, column);
       for (auto* child : children)
-        gridItemsToBePainted.append(
+        gridItemsToBePainted.push_back(
             std::make_pair(child, m_layoutGrid.paintIndexForGridItem(child)));
     }
   }
 
   for (auto* item : m_layoutGrid.itemsOverflowingGridArea()) {
     if (item->frameRect().intersects(localVisualRect))
-      gridItemsToBePainted.append(
+      gridItemsToBePainted.push_back(
           std::make_pair(item, m_layoutGrid.paintIndexForGridItem(item)));
   }
 
diff --git a/third_party/WebKit/Source/core/paint/LayerClipRecorder.cpp b/third_party/WebKit/Source/core/paint/LayerClipRecorder.cpp
index 3d85217..8db79bb 100644
--- a/third_party/WebKit/Source/core/paint/LayerClipRecorder.cpp
+++ b/third_party/WebKit/Source/core/paint/LayerClipRecorder.cpp
@@ -93,7 +93,7 @@
       LayoutSize size(layer->layoutBox()
                           ? toLayoutBox(layer->layoutObject())->size()
                           : LayoutSize(layer->size()));
-      roundedRectClips.append(
+      roundedRectClips.push_back(
           layer->layoutObject()->style()->getRoundedInnerBorderFor(
               LayoutRect(delta, size)));
     }
diff --git a/third_party/WebKit/Source/core/paint/ObjectPainter.cpp b/third_party/WebKit/Source/core/paint/ObjectPainter.cpp
index d34c512..5ef1029 100644
--- a/third_party/WebKit/Source/core/paint/ObjectPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/ObjectPainter.cpp
@@ -258,7 +258,7 @@
 
   Vector<IntRect> pixelSnappedOutlineRects;
   for (auto& r : outlineRects)
-    pixelSnappedOutlineRects.append(pixelSnappedIntRect(r));
+    pixelSnappedOutlineRects.push_back(pixelSnappedIntRect(r));
 
   IntRect unitedOutlineRect = unionRectEvenIfEmpty(pixelSnappedOutlineRects);
   IntRect bounds = unitedOutlineRect;
diff --git a/third_party/WebKit/Source/core/paint/PaintInvalidator.cpp b/third_party/WebKit/Source/core/paint/PaintInvalidator.cpp
index d58c042..f3f7f8b 100644
--- a/third_party/WebKit/Source/core/paint/PaintInvalidator.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintInvalidator.cpp
@@ -420,7 +420,7 @@
   PaintInvalidationReason reason = object.invalidatePaintIfNeeded(context);
   switch (reason) {
     case PaintInvalidationDelayedFull:
-      m_pendingDelayedPaintInvalidations.append(&object);
+      m_pendingDelayedPaintInvalidations.push_back(&object);
       break;
     case PaintInvalidationSubtree:
       context.forcedSubtreeInvalidationFlags |=
diff --git a/third_party/WebKit/Source/core/paint/PaintLayer.cpp b/third_party/WebKit/Source/core/paint/PaintLayer.cpp
index d41f3916..02e2e26 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayer.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayer.cpp
@@ -1546,7 +1546,7 @@
   clipper().calculateRects(clipRectsContext, dirtyRect, fragment.layerBounds,
                            fragment.backgroundRect, fragment.foregroundRect,
                            offsetFromRoot);
-  fragments.append(fragment);
+  fragments.push_back(fragment);
 }
 
 bool PaintLayer::shouldFragmentCompositedBounds(
@@ -1692,7 +1692,7 @@
     // cases, but there should be no reason to do so. Either filter them out
     // here, or, even better: pass a better clip rectangle to the fragmentainer
     // iterator, so that we won't end up with empty fragments here.
-    fragments.append(fragment);
+    fragments.push_back(fragment);
   }
 }
 
@@ -2983,7 +2983,7 @@
   FilterOperations filterOperations = style.filter();
   if (layoutObject()->hasReflection() && layoutObject()->isBox()) {
     BoxReflection reflection = boxReflectionForPaintLayer(*this, style);
-    filterOperations.operations().append(
+    filterOperations.operations().push_back(
         BoxReflectFilterOperation::create(reflection));
   }
   return filterOperations;
@@ -3109,20 +3109,20 @@
       // composited layer. Skip reporting contents for non-composited layers as
       // they'll get projected to the same layer as the bounding box.
       if (compositingState() != NotComposited)
-        rect.append(m_scrollableArea->overflowRect());
+        rect.push_back(m_scrollableArea->overflowRect());
 
       rects.set(this, rect);
       if (const PaintLayer* parentLayer = parent()) {
         LayerHitTestRects::iterator iter = rects.find(parentLayer);
         if (iter == rects.end()) {
           rects.add(parentLayer, Vector<LayoutRect>())
-              .storedValue->value.append(physicalBoundingBox(parentLayer));
+              .storedValue->value.push_back(physicalBoundingBox(parentLayer));
         } else {
-          iter->value.append(physicalBoundingBox(parentLayer));
+          iter->value.push_back(physicalBoundingBox(parentLayer));
         }
       }
     } else {
-      rect.append(logicalBoundingBox());
+      rect.push_back(logicalBoundingBox());
       rects.set(this, rect);
     }
   }
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp b/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp
index 5cadf529..e8d2e4aa 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp
@@ -648,7 +648,7 @@
   LayoutPoint offsetFromRoot;
   m_paintLayer.convertToLayerCoords(paintingInfo.rootLayer, offsetFromRoot);
   LayoutSize offsetAdjustment = m_paintLayer.location() - offsetFromRoot;
-  layerFragments.append(singleFragmentIgnoredPagination);
+  layerFragments.push_back(singleFragmentIgnoredPagination);
   layerFragments[0].paginationOffset += offsetAdjustment;
   layerFragments[0].layerBounds.move(offsetAdjustment);
 
@@ -657,7 +657,7 @@
     PaintLayerFragment fragment = layerFragments[i - 1];
     fragment.paginationOffset += pageOffset;
     fragment.layerBounds.moveBy(pageOffset);
-    layerFragments.append(fragment);
+    layerFragments.push_back(fragment);
   }
 }
 
@@ -690,7 +690,7 @@
     if (isFixedPositionObjectInPagedMedia)
       repeatFixedPositionObjectInPages(fragment, paintingInfo, layerFragments);
     else
-      layerFragments.append(fragment);
+      layerFragments.push_back(fragment);
   } else {
     // FIXME: This is a mess. Look closely at this code and the code in Layer
     // and fix any issues in it & refactor to make it obvious from code
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp b/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
index 8f2680f..081d5ed 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
@@ -2054,7 +2054,7 @@
   if (!s_needsRelayout)
     s_needsRelayout =
         new PersistentHeapVector<Member<PaintLayerScrollableArea>>();
-  s_needsRelayout->append(&scrollableArea);
+  s_needsRelayout->push_back(&scrollableArea);
 }
 
 void PaintLayerScrollableArea::PreventRelayoutScope::resetRelayoutNeeded() {
@@ -2088,7 +2088,7 @@
     PaintLayerScrollableArea* scrollableArea) {
   if (!scrollableArea->needsScrollOffsetClamp()) {
     scrollableArea->setNeedsScrollOffsetClamp(true);
-    s_needsClamp->append(scrollableArea);
+    s_needsClamp->push_back(scrollableArea);
   }
 }
 
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerStackingNode.cpp b/third_party/WebKit/Source/core/paint/PaintLayerStackingNode.cpp
index b990834..a026998 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerStackingNode.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayerStackingNode.cpp
@@ -162,7 +162,7 @@
           m_posZOrderList =
               WTF::wrapUnique(new Vector<PaintLayerStackingNode*>);
         }
-        m_posZOrderList->append(layer->stackingNode());
+        m_posZOrderList->push_back(layer->stackingNode());
       }
     }
   }
@@ -185,7 +185,7 @@
         (zIndex() >= 0) ? posBuffer : negBuffer;
     if (!buffer)
       buffer = WTF::wrapUnique(new Vector<PaintLayerStackingNode*>);
-    buffer->append(this);
+    buffer->push_back(this);
   }
 
   if (!isStackingContext()) {
diff --git a/third_party/WebKit/Source/core/paint/RoundedInnerRectClipper.cpp b/third_party/WebKit/Source/core/paint/RoundedInnerRectClipper.cpp
index 520c2e0..6aee6c1 100644
--- a/third_party/WebKit/Source/core/paint/RoundedInnerRectClipper.cpp
+++ b/third_party/WebKit/Source/core/paint/RoundedInnerRectClipper.cpp
@@ -24,7 +24,7 @@
                                       : DisplayItem::kClipBoxPaintPhaseFirst) {
   Vector<FloatRoundedRect> roundedRectClips;
   if (clipRect.isRenderable()) {
-    roundedRectClips.append(clipRect);
+    roundedRectClips.push_back(clipRect);
   } else {
     // We create a rounded rect for each of the corners and clip it, while
     // making sure we clip opposing corners together.
@@ -35,14 +35,14 @@
                           rect.maxY() - clipRect.rect().y());
       FloatRoundedRect::Radii topCornerRadii;
       topCornerRadii.setTopLeft(clipRect.getRadii().topLeft());
-      roundedRectClips.append(FloatRoundedRect(topCorner, topCornerRadii));
+      roundedRectClips.push_back(FloatRoundedRect(topCorner, topCornerRadii));
 
       FloatRect bottomCorner(rect.x().toFloat(), rect.y().toFloat(),
                              clipRect.rect().maxX() - rect.x().toFloat(),
                              clipRect.rect().maxY() - rect.y().toFloat());
       FloatRoundedRect::Radii bottomCornerRadii;
       bottomCornerRadii.setBottomRight(clipRect.getRadii().bottomRight());
-      roundedRectClips.append(
+      roundedRectClips.push_back(
           FloatRoundedRect(bottomCorner, bottomCornerRadii));
     }
 
@@ -53,14 +53,14 @@
                           rect.maxY() - clipRect.rect().y());
       FloatRoundedRect::Radii topCornerRadii;
       topCornerRadii.setTopRight(clipRect.getRadii().topRight());
-      roundedRectClips.append(FloatRoundedRect(topCorner, topCornerRadii));
+      roundedRectClips.push_back(FloatRoundedRect(topCorner, topCornerRadii));
 
       FloatRect bottomCorner(clipRect.rect().x(), rect.y().toFloat(),
                              rect.maxX() - clipRect.rect().x(),
                              clipRect.rect().maxY() - rect.y().toFloat());
       FloatRoundedRect::Radii bottomCornerRadii;
       bottomCornerRadii.setBottomLeft(clipRect.getRadii().bottomLeft());
-      roundedRectClips.append(
+      roundedRectClips.push_back(
           FloatRoundedRect(bottomCorner, bottomCornerRadii));
     }
   }
diff --git a/third_party/WebKit/Source/core/paint/SVGInlineTextBoxPainter.cpp b/third_party/WebKit/Source/core/paint/SVGInlineTextBoxPainter.cpp
index dcc31c7..f992bd60 100644
--- a/third_party/WebKit/Source/core/paint/SVGInlineTextBoxPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/SVGInlineTextBoxPainter.cpp
@@ -575,7 +575,7 @@
             fragment, fragmentStartPosition, fragmentEndPosition))
       continue;
 
-    fragmentInfoList.append(SVGTextFragmentWithRange(
+    fragmentInfoList.push_back(SVGTextFragmentWithRange(
         fragment, fragmentStartPosition, fragmentEndPosition));
   }
   return fragmentInfoList;
diff --git a/third_party/WebKit/Source/core/paint/TableSectionPainter.cpp b/third_party/WebKit/Source/core/paint/TableSectionPainter.cpp
index f9e7945..983c326 100644
--- a/third_party/WebKit/Source/core/paint/TableSectionPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/TableSectionPainter.cpp
@@ -314,7 +314,7 @@
             if (!spanningCells.add(cell).isNewEntry)
               continue;
           }
-          cells.append(cell);
+          cells.push_back(cell);
         }
       }
     }
diff --git a/third_party/WebKit/Source/core/style/BasicShapes.h b/third_party/WebKit/Source/core/style/BasicShapes.h
index 225af2f..4313578 100644
--- a/third_party/WebKit/Source/core/style/BasicShapes.h
+++ b/third_party/WebKit/Source/core/style/BasicShapes.h
@@ -233,8 +233,8 @@
 
   void setWindRule(WindRule windRule) { m_windRule = windRule; }
   void appendPoint(const Length& x, const Length& y) {
-    m_values.append(x);
-    m_values.append(y);
+    m_values.push_back(x);
+    m_values.push_back(y);
   }
 
   void path(Path&, const FloatRect&) override;
diff --git a/third_party/WebKit/Source/core/style/ComputedStyle.cpp b/third_party/WebKit/Source/core/style/ComputedStyle.cpp
index e6a194c..23deafc 100644
--- a/third_party/WebKit/Source/core/style/ComputedStyle.cpp
+++ b/third_party/WebKit/Source/core/style/ComputedStyle.cpp
@@ -470,7 +470,7 @@
   if (!m_cachedPseudoStyles)
     m_cachedPseudoStyles = WTF::wrapUnique(new PseudoStyleCache);
 
-  m_cachedPseudoStyles->append(pseudo);
+  m_cachedPseudoStyles->push_back(pseudo);
 
   return result;
 }
@@ -1136,7 +1136,7 @@
     m_rareNonInheritedData.access()->m_paintImages =
         WTF::makeUnique<Vector<Persistent<StyleImage>>>();
   }
-  m_rareNonInheritedData.access()->m_paintImages->append(image);
+  m_rareNonInheritedData.access()->m_paintImages->push_back(image);
 }
 
 void ComputedStyle::addCursor(StyleImage* image,
@@ -1144,7 +1144,7 @@
                               const IntPoint& hotSpot) {
   if (!m_rareInheritedData.access()->cursorData)
     m_rareInheritedData.access()->cursorData = new CursorList;
-  m_rareInheritedData.access()->cursorData->append(
+  m_rareInheritedData.access()->cursorData->push_back(
       CursorData(image, hotSpotSpecified, hotSpot));
 }
 
@@ -1226,7 +1226,7 @@
 
 void ComputedStyle::addCallbackSelector(const String& selector) {
   if (!m_rareNonInheritedData->m_callbackSelectors.contains(selector))
-    m_rareNonInheritedData.access()->m_callbackSelectors.append(selector);
+    m_rareNonInheritedData.access()->m_callbackSelectors.push_back(selector);
 }
 
 void ComputedStyle::setContent(ContentData* contentData) {
diff --git a/third_party/WebKit/Source/core/style/FilterOperationsTest.cpp b/third_party/WebKit/Source/core/style/FilterOperationsTest.cpp
index 5deb747..969d995 100644
--- a/third_party/WebKit/Source/core/style/FilterOperationsTest.cpp
+++ b/third_party/WebKit/Source/core/style/FilterOperationsTest.cpp
@@ -38,7 +38,7 @@
 
 TEST(FilterOperationsTest, mapRectBlur) {
   FilterOperations ops;
-  ops.operations().append(BlurFilterOperation::create(Length(20.0, Fixed)));
+  ops.operations().push_back(BlurFilterOperation::create(Length(20.0, Fixed)));
   EXPECT_TRUE(ops.hasFilterThatMovesPixels());
   EXPECT_EQ(IntRect(-57, -57, 124, 124),
             enclosingIntRect(ops.mapRect(FloatRect(0, 0, 10, 10))));
@@ -46,7 +46,7 @@
 
 TEST(FilterOperationsTest, mapRectDropShadow) {
   FilterOperations ops;
-  ops.operations().append(DropShadowFilterOperation::create(
+  ops.operations().push_back(DropShadowFilterOperation::create(
       ShadowData(FloatPoint(3, 8), 20, 0, Normal, StyleColor(Color(1, 2, 3)))));
   EXPECT_TRUE(ops.hasFilterThatMovesPixels());
   EXPECT_EQ(IntRect(-54, -49, 124, 124),
@@ -55,7 +55,7 @@
 
 TEST(FilterOperationsTest, mapRectBoxReflect) {
   FilterOperations ops;
-  ops.operations().append(BoxReflectFilterOperation::create(
+  ops.operations().push_back(BoxReflectFilterOperation::create(
       BoxReflection(BoxReflection::VerticalReflection, 100)));
   EXPECT_TRUE(ops.hasFilterThatMovesPixels());
 
@@ -67,9 +67,9 @@
   // This is a case where the order of filter operations matters, and it's
   // important that the bounds be filtered in the correct order.
   FilterOperations ops;
-  ops.operations().append(DropShadowFilterOperation::create(ShadowData(
+  ops.operations().push_back(DropShadowFilterOperation::create(ShadowData(
       FloatPoint(100, 200), 0, 0, Normal, StyleColor(Color::black))));
-  ops.operations().append(BoxReflectFilterOperation::create(
+  ops.operations().push_back(BoxReflectFilterOperation::create(
       BoxReflection(BoxReflection::VerticalReflection, 50)));
   EXPECT_TRUE(ops.hasFilterThatMovesPixels());
   EXPECT_EQ(FloatRect(0, -160, 110, 370), ops.mapRect(FloatRect(0, 0, 10, 10)));
diff --git a/third_party/WebKit/Source/core/style/QuotesData.cpp b/third_party/WebKit/Source/core/style/QuotesData.cpp
index 470dbac9..5b088c6 100644
--- a/third_party/WebKit/Source/core/style/QuotesData.cpp
+++ b/third_party/WebKit/Source/core/style/QuotesData.cpp
@@ -34,7 +34,7 @@
 }
 
 void QuotesData::addPair(std::pair<String, String> quotePair) {
-  m_quotePairs.append(quotePair);
+  m_quotePairs.push_back(quotePair);
 }
 
 const String QuotesData::getOpenQuote(int index) const {
diff --git a/third_party/WebKit/Source/core/style/ShadowList.cpp b/third_party/WebKit/Source/core/style/ShadowList.cpp
index 9c275ab..31fa5a1c 100644
--- a/third_party/WebKit/Source/core/style/ShadowList.cpp
+++ b/third_party/WebKit/Source/core/style/ShadowList.cpp
@@ -76,7 +76,7 @@
     else if (!toShadow)
       toShadow = fromShadow->style() == Inset ? &defaultInsetShadowData
                                               : &defaultShadowData;
-    shadows.append(toShadow->blend(*fromShadow, progress, currentColor));
+    shadows.push_back(toShadow->blend(*fromShadow, progress, currentColor));
   }
 
   return ShadowList::adopt(shadows);
diff --git a/third_party/WebKit/Source/core/svg/SVGAngle.cpp b/third_party/WebKit/Source/core/svg/SVGAngle.cpp
index 70b6937d..3924f93 100644
--- a/third_party/WebKit/Source/core/svg/SVGAngle.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGAngle.cpp
@@ -33,9 +33,9 @@
 getStaticStringEntries<SVGMarkerOrientType>() {
   DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
   if (entries.isEmpty()) {
-    entries.append(std::make_pair(SVGMarkerOrientAuto, "auto"));
-    entries.append(std::make_pair(SVGMarkerOrientAngle, "angle"));
-    entries.append(
+    entries.push_back(std::make_pair(SVGMarkerOrientAuto, "auto"));
+    entries.push_back(std::make_pair(SVGMarkerOrientAngle, "angle"));
+    entries.push_back(
         std::make_pair(SVGMarkerOrientAutoStartReverse, "auto-start-reverse"));
   }
   return entries;
diff --git a/third_party/WebKit/Source/core/svg/SVGAnimationElement.cpp b/third_party/WebKit/Source/core/svg/SVGAnimationElement.cpp
index 10150ac..62bb324 100644
--- a/third_party/WebKit/Source/core/svg/SVGAnimationElement.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGAnimationElement.cpp
@@ -60,7 +60,7 @@
         goto fail;
     } else {
       parseList[i] = parseList[i].stripWhiteSpace();
-      result.append(parseList[i]);
+      result.push_back(parseList[i]);
     }
   }
 
@@ -90,7 +90,7 @@
         goto fail;
       }
     }
-    result.append(time);
+    result.push_back(time);
   }
   return true;
 fail:
@@ -129,7 +129,7 @@
       ptr++;
     skipOptionalSVGSpaces(ptr, end);
 
-    result.append(gfx::CubicBezier(posA, posB, posC, posD));
+    result.push_back(gfx::CubicBezier(posA, posB, posC, posD));
   }
 
   return ptr == end;
@@ -343,14 +343,14 @@
 
   Vector<float> keyTimesForPaced;
   float totalDistance = 0;
-  keyTimesForPaced.append(0);
+  keyTimesForPaced.push_back(0);
   for (unsigned n = 0; n < valuesCount - 1; ++n) {
     // Distance in any units
     float distance = calculateDistance(m_values[n], m_values[n + 1]);
     if (distance < 0)
       return;
     totalDistance += distance;
-    keyTimesForPaced.append(distance);
+    keyTimesForPaced.push_back(distance);
   }
   if (!totalDistance)
     return;
diff --git a/third_party/WebKit/Source/core/svg/SVGComponentTransferFunctionElement.cpp b/third_party/WebKit/Source/core/svg/SVGComponentTransferFunctionElement.cpp
index 2b114e5f..fa66000 100644
--- a/third_party/WebKit/Source/core/svg/SVGComponentTransferFunctionElement.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGComponentTransferFunctionElement.cpp
@@ -32,13 +32,14 @@
 getStaticStringEntries<ComponentTransferType>() {
   DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
   if (entries.isEmpty()) {
-    entries.append(
+    entries.push_back(
         std::make_pair(FECOMPONENTTRANSFER_TYPE_IDENTITY, "identity"));
-    entries.append(std::make_pair(FECOMPONENTTRANSFER_TYPE_TABLE, "table"));
-    entries.append(
+    entries.push_back(std::make_pair(FECOMPONENTTRANSFER_TYPE_TABLE, "table"));
+    entries.push_back(
         std::make_pair(FECOMPONENTTRANSFER_TYPE_DISCRETE, "discrete"));
-    entries.append(std::make_pair(FECOMPONENTTRANSFER_TYPE_LINEAR, "linear"));
-    entries.append(std::make_pair(FECOMPONENTTRANSFER_TYPE_GAMMA, "gamma"));
+    entries.push_back(
+        std::make_pair(FECOMPONENTTRANSFER_TYPE_LINEAR, "linear"));
+    entries.push_back(std::make_pair(FECOMPONENTTRANSFER_TYPE_GAMMA, "gamma"));
   }
   return entries;
 }
diff --git a/third_party/WebKit/Source/core/svg/SVGDocumentExtensions.cpp b/third_party/WebKit/Source/core/svg/SVGDocumentExtensions.cpp
index 6e672b2..d6b7b67 100644
--- a/third_party/WebKit/Source/core/svg/SVGDocumentExtensions.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGDocumentExtensions.cpp
@@ -225,7 +225,7 @@
 
     elements->remove(element);
     if (elements->isEmpty())
-      toBeRemoved.append(entry.key);
+      toBeRemoved.push_back(entry.key);
   }
 
   clearHasPendingResourcesIfPossible(element);
diff --git a/third_party/WebKit/Source/core/svg/SVGFEBlendElement.cpp b/third_party/WebKit/Source/core/svg/SVGFEBlendElement.cpp
index ab6ece9..4c4f23c 100644
--- a/third_party/WebKit/Source/core/svg/SVGFEBlendElement.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGFEBlendElement.cpp
@@ -60,29 +60,32 @@
 getStaticStringEntries<SVGFEBlendElement::Mode>() {
   DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
   if (entries.isEmpty()) {
-    entries.append(std::make_pair(SVGFEBlendElement::ModeNormal, "normal"));
-    entries.append(std::make_pair(SVGFEBlendElement::ModeMultiply, "multiply"));
-    entries.append(std::make_pair(SVGFEBlendElement::ModeScreen, "screen"));
-    entries.append(std::make_pair(SVGFEBlendElement::ModeDarken, "darken"));
-    entries.append(std::make_pair(SVGFEBlendElement::ModeLighten, "lighten"));
-    entries.append(std::make_pair(SVGFEBlendElement::ModeOverlay, "overlay"));
-    entries.append(
+    entries.push_back(std::make_pair(SVGFEBlendElement::ModeNormal, "normal"));
+    entries.push_back(
+        std::make_pair(SVGFEBlendElement::ModeMultiply, "multiply"));
+    entries.push_back(std::make_pair(SVGFEBlendElement::ModeScreen, "screen"));
+    entries.push_back(std::make_pair(SVGFEBlendElement::ModeDarken, "darken"));
+    entries.push_back(
+        std::make_pair(SVGFEBlendElement::ModeLighten, "lighten"));
+    entries.push_back(
+        std::make_pair(SVGFEBlendElement::ModeOverlay, "overlay"));
+    entries.push_back(
         std::make_pair(SVGFEBlendElement::ModeColorDodge, "color-dodge"));
-    entries.append(
+    entries.push_back(
         std::make_pair(SVGFEBlendElement::ModeColorBurn, "color-burn"));
-    entries.append(
+    entries.push_back(
         std::make_pair(SVGFEBlendElement::ModeHardLight, "hard-light"));
-    entries.append(
+    entries.push_back(
         std::make_pair(SVGFEBlendElement::ModeSoftLight, "soft-light"));
-    entries.append(
+    entries.push_back(
         std::make_pair(SVGFEBlendElement::ModeDifference, "difference"));
-    entries.append(
+    entries.push_back(
         std::make_pair(SVGFEBlendElement::ModeExclusion, "exclusion"));
-    entries.append(std::make_pair(SVGFEBlendElement::ModeHue, "hue"));
-    entries.append(
+    entries.push_back(std::make_pair(SVGFEBlendElement::ModeHue, "hue"));
+    entries.push_back(
         std::make_pair(SVGFEBlendElement::ModeSaturation, "saturation"));
-    entries.append(std::make_pair(SVGFEBlendElement::ModeColor, "color"));
-    entries.append(
+    entries.push_back(std::make_pair(SVGFEBlendElement::ModeColor, "color"));
+    entries.push_back(
         std::make_pair(SVGFEBlendElement::ModeLuminosity, "luminosity"));
   }
   return entries;
@@ -155,8 +158,8 @@
       filter, toWebBlendMode(m_mode->currentValue()->enumValue()));
   FilterEffectVector& inputEffects = effect->inputEffects();
   inputEffects.reserveCapacity(2);
-  inputEffects.append(input1);
-  inputEffects.append(input2);
+  inputEffects.push_back(input1);
+  inputEffects.push_back(input2);
   return effect;
 }
 
diff --git a/third_party/WebKit/Source/core/svg/SVGFEColorMatrixElement.cpp b/third_party/WebKit/Source/core/svg/SVGFEColorMatrixElement.cpp
index 6bc8baf..05eeb530 100644
--- a/third_party/WebKit/Source/core/svg/SVGFEColorMatrixElement.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGFEColorMatrixElement.cpp
@@ -29,11 +29,12 @@
 const SVGEnumerationStringEntries& getStaticStringEntries<ColorMatrixType>() {
   DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
   if (entries.isEmpty()) {
-    entries.append(std::make_pair(FECOLORMATRIX_TYPE_MATRIX, "matrix"));
-    entries.append(std::make_pair(FECOLORMATRIX_TYPE_SATURATE, "saturate"));
-    entries.append(std::make_pair(FECOLORMATRIX_TYPE_HUEROTATE, "hueRotate"));
-    entries.append(std::make_pair(FECOLORMATRIX_TYPE_LUMINANCETOALPHA,
-                                  "luminanceToAlpha"));
+    entries.push_back(std::make_pair(FECOLORMATRIX_TYPE_MATRIX, "matrix"));
+    entries.push_back(std::make_pair(FECOLORMATRIX_TYPE_SATURATE, "saturate"));
+    entries.push_back(
+        std::make_pair(FECOLORMATRIX_TYPE_HUEROTATE, "hueRotate"));
+    entries.push_back(std::make_pair(FECOLORMATRIX_TYPE_LUMINANCETOALPHA,
+                                     "luminanceToAlpha"));
   }
   return entries;
 }
@@ -101,7 +102,7 @@
   Vector<float> filterValues = m_values->currentValue()->toFloatVector();
   FilterEffect* effect =
       FEColorMatrix::create(filter, filterType, filterValues);
-  effect->inputEffects().append(input1);
+  effect->inputEffects().push_back(input1);
   return effect;
 }
 
diff --git a/third_party/WebKit/Source/core/svg/SVGFEComponentTransferElement.cpp b/third_party/WebKit/Source/core/svg/SVGFEComponentTransferElement.cpp
index 37a0a9a..bbd0ac8 100644
--- a/third_party/WebKit/Source/core/svg/SVGFEComponentTransferElement.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGFEComponentTransferElement.cpp
@@ -83,7 +83,7 @@
 
   FilterEffect* effect =
       FEComponentTransfer::create(filter, red, green, blue, alpha);
-  effect->inputEffects().append(input1);
+  effect->inputEffects().push_back(input1);
   return effect;
 }
 
diff --git a/third_party/WebKit/Source/core/svg/SVGFECompositeElement.cpp b/third_party/WebKit/Source/core/svg/SVGFECompositeElement.cpp
index 95ca05a..619a7b5 100644
--- a/third_party/WebKit/Source/core/svg/SVGFECompositeElement.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGFECompositeElement.cpp
@@ -30,14 +30,14 @@
 getStaticStringEntries<CompositeOperationType>() {
   DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
   if (entries.isEmpty()) {
-    entries.append(std::make_pair(FECOMPOSITE_OPERATOR_OVER, "over"));
-    entries.append(std::make_pair(FECOMPOSITE_OPERATOR_IN, "in"));
-    entries.append(std::make_pair(FECOMPOSITE_OPERATOR_OUT, "out"));
-    entries.append(std::make_pair(FECOMPOSITE_OPERATOR_ATOP, "atop"));
-    entries.append(std::make_pair(FECOMPOSITE_OPERATOR_XOR, "xor"));
-    entries.append(
+    entries.push_back(std::make_pair(FECOMPOSITE_OPERATOR_OVER, "over"));
+    entries.push_back(std::make_pair(FECOMPOSITE_OPERATOR_IN, "in"));
+    entries.push_back(std::make_pair(FECOMPOSITE_OPERATOR_OUT, "out"));
+    entries.push_back(std::make_pair(FECOMPOSITE_OPERATOR_ATOP, "atop"));
+    entries.push_back(std::make_pair(FECOMPOSITE_OPERATOR_XOR, "xor"));
+    entries.push_back(
         std::make_pair(FECOMPOSITE_OPERATOR_ARITHMETIC, "arithmetic"));
-    entries.append(std::make_pair(FECOMPOSITE_OPERATOR_LIGHTER, "lighter"));
+    entries.push_back(std::make_pair(FECOMPOSITE_OPERATOR_LIGHTER, "lighter"));
   }
   return entries;
 }
@@ -140,8 +140,8 @@
       m_k3->currentValue()->value(), m_k4->currentValue()->value());
   FilterEffectVector& inputEffects = effect->inputEffects();
   inputEffects.reserveCapacity(2);
-  inputEffects.append(input1);
-  inputEffects.append(input2);
+  inputEffects.push_back(input1);
+  inputEffects.push_back(input2);
   return effect;
 }
 
diff --git a/third_party/WebKit/Source/core/svg/SVGFEConvolveMatrixElement.cpp b/third_party/WebKit/Source/core/svg/SVGFEConvolveMatrixElement.cpp
index e7acb7e..276a47a 100644
--- a/third_party/WebKit/Source/core/svg/SVGFEConvolveMatrixElement.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGFEConvolveMatrixElement.cpp
@@ -31,9 +31,9 @@
 const SVGEnumerationStringEntries& getStaticStringEntries<EdgeModeType>() {
   DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
   if (entries.isEmpty()) {
-    entries.append(std::make_pair(EDGEMODE_DUPLICATE, "duplicate"));
-    entries.append(std::make_pair(EDGEMODE_WRAP, "wrap"));
-    entries.append(std::make_pair(EDGEMODE_NONE, "none"));
+    entries.push_back(std::make_pair(EDGEMODE_DUPLICATE, "duplicate"));
+    entries.push_back(std::make_pair(EDGEMODE_WRAP, "wrap"));
+    entries.push_back(std::make_pair(EDGEMODE_NONE, "none"));
   }
   return entries;
 }
@@ -211,7 +211,7 @@
       targetPoint(), m_edgeMode->currentValue()->enumValue(),
       m_preserveAlpha->currentValue()->value(),
       m_kernelMatrix->currentValue()->toFloatVector());
-  effect->inputEffects().append(input1);
+  effect->inputEffects().push_back(input1);
   return effect;
 }
 
diff --git a/third_party/WebKit/Source/core/svg/SVGFEDiffuseLightingElement.cpp b/third_party/WebKit/Source/core/svg/SVGFEDiffuseLightingElement.cpp
index 0f2018f..1ff992c 100644
--- a/third_party/WebKit/Source/core/svg/SVGFEDiffuseLightingElement.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGFEDiffuseLightingElement.cpp
@@ -161,7 +161,7 @@
   FilterEffect* effect = FEDiffuseLighting::create(
       filter, color, m_surfaceScale->currentValue()->value(),
       m_diffuseConstant->currentValue()->value(), lightSource.release());
-  effect->inputEffects().append(input1);
+  effect->inputEffects().push_back(input1);
   return effect;
 }
 
diff --git a/third_party/WebKit/Source/core/svg/SVGFEDisplacementMapElement.cpp b/third_party/WebKit/Source/core/svg/SVGFEDisplacementMapElement.cpp
index 3b53d54..adc9664 100644
--- a/third_party/WebKit/Source/core/svg/SVGFEDisplacementMapElement.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGFEDisplacementMapElement.cpp
@@ -29,10 +29,10 @@
 getStaticStringEntries<ChannelSelectorType>() {
   DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
   if (entries.isEmpty()) {
-    entries.append(std::make_pair(CHANNEL_R, "R"));
-    entries.append(std::make_pair(CHANNEL_G, "G"));
-    entries.append(std::make_pair(CHANNEL_B, "B"));
-    entries.append(std::make_pair(CHANNEL_A, "A"));
+    entries.push_back(std::make_pair(CHANNEL_R, "R"));
+    entries.push_back(std::make_pair(CHANNEL_G, "G"));
+    entries.push_back(std::make_pair(CHANNEL_B, "B"));
+    entries.push_back(std::make_pair(CHANNEL_A, "A"));
   }
   return entries;
 }
@@ -123,8 +123,8 @@
       m_scale->currentValue()->value());
   FilterEffectVector& inputEffects = effect->inputEffects();
   inputEffects.reserveCapacity(2);
-  inputEffects.append(input1);
-  inputEffects.append(input2);
+  inputEffects.push_back(input1);
+  inputEffects.push_back(input2);
   return effect;
 }
 
diff --git a/third_party/WebKit/Source/core/svg/SVGFEDropShadowElement.cpp b/third_party/WebKit/Source/core/svg/SVGFEDropShadowElement.cpp
index 0fbdc43..e191ded4 100644
--- a/third_party/WebKit/Source/core/svg/SVGFEDropShadowElement.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGFEDropShadowElement.cpp
@@ -117,7 +117,7 @@
   FilterEffect* effect = FEDropShadow::create(
       filter, stdDevX, stdDevY, m_dx->currentValue()->value(),
       m_dy->currentValue()->value(), color, opacity);
-  effect->inputEffects().append(input1);
+  effect->inputEffects().push_back(input1);
   return effect;
 }
 
diff --git a/third_party/WebKit/Source/core/svg/SVGFEGaussianBlurElement.cpp b/third_party/WebKit/Source/core/svg/SVGFEGaussianBlurElement.cpp
index dc9d611..eec9e73 100644
--- a/third_party/WebKit/Source/core/svg/SVGFEGaussianBlurElement.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGFEGaussianBlurElement.cpp
@@ -78,7 +78,7 @@
   float stdDevX = std::max(0.0f, stdDeviationX()->currentValue()->value());
   float stdDevY = std::max(0.0f, stdDeviationY()->currentValue()->value());
   FilterEffect* effect = FEGaussianBlur::create(filter, stdDevX, stdDevY);
-  effect->inputEffects().append(input1);
+  effect->inputEffects().push_back(input1);
   return effect;
 }
 
diff --git a/third_party/WebKit/Source/core/svg/SVGFEMergeElement.cpp b/third_party/WebKit/Source/core/svg/SVGFEMergeElement.cpp
index 6b07d3c..3d6c13d 100644
--- a/third_party/WebKit/Source/core/svg/SVGFEMergeElement.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGFEMergeElement.cpp
@@ -42,7 +42,7 @@
     FilterEffect* mergeEffect = filterBuilder->getEffectById(
         AtomicString(mergeNode.in1()->currentValue()->value()));
     ASSERT(mergeEffect);
-    mergeInputs.append(mergeEffect);
+    mergeInputs.push_back(mergeEffect);
   }
   return effect;
 }
diff --git a/third_party/WebKit/Source/core/svg/SVGFEMorphologyElement.cpp b/third_party/WebKit/Source/core/svg/SVGFEMorphologyElement.cpp
index e2e8f84a..3d05d6e4 100644
--- a/third_party/WebKit/Source/core/svg/SVGFEMorphologyElement.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGFEMorphologyElement.cpp
@@ -29,8 +29,8 @@
 getStaticStringEntries<MorphologyOperatorType>() {
   DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
   if (entries.isEmpty()) {
-    entries.append(std::make_pair(FEMORPHOLOGY_OPERATOR_ERODE, "erode"));
-    entries.append(std::make_pair(FEMORPHOLOGY_OPERATOR_DILATE, "dilate"));
+    entries.push_back(std::make_pair(FEMORPHOLOGY_OPERATOR_ERODE, "erode"));
+    entries.push_back(std::make_pair(FEMORPHOLOGY_OPERATOR_DILATE, "dilate"));
   }
   return entries;
 }
@@ -111,7 +111,7 @@
   float yRadius = radiusY()->currentValue()->value();
   FilterEffect* effect = FEMorphology::create(
       filter, m_svgOperator->currentValue()->enumValue(), xRadius, yRadius);
-  effect->inputEffects().append(input1);
+  effect->inputEffects().push_back(input1);
   return effect;
 }
 
diff --git a/third_party/WebKit/Source/core/svg/SVGFEOffsetElement.cpp b/third_party/WebKit/Source/core/svg/SVGFEOffsetElement.cpp
index 3c68a29..5f0e11c 100644
--- a/third_party/WebKit/Source/core/svg/SVGFEOffsetElement.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGFEOffsetElement.cpp
@@ -68,7 +68,7 @@
 
   FilterEffect* effect = FEOffset::create(filter, m_dx->currentValue()->value(),
                                           m_dy->currentValue()->value());
-  effect->inputEffects().append(input1);
+  effect->inputEffects().push_back(input1);
   return effect;
 }
 
diff --git a/third_party/WebKit/Source/core/svg/SVGFESpecularLightingElement.cpp b/third_party/WebKit/Source/core/svg/SVGFESpecularLightingElement.cpp
index 574dc0ef..838c412f 100644
--- a/third_party/WebKit/Source/core/svg/SVGFESpecularLightingElement.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGFESpecularLightingElement.cpp
@@ -175,7 +175,7 @@
       filter, color, m_surfaceScale->currentValue()->value(),
       m_specularConstant->currentValue()->value(),
       m_specularExponent->currentValue()->value(), lightSource.release());
-  effect->inputEffects().append(input1);
+  effect->inputEffects().push_back(input1);
   return effect;
 }
 
diff --git a/third_party/WebKit/Source/core/svg/SVGFETileElement.cpp b/third_party/WebKit/Source/core/svg/SVGFETileElement.cpp
index 86581b9..71d8ae0 100644
--- a/third_party/WebKit/Source/core/svg/SVGFETileElement.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGFETileElement.cpp
@@ -56,7 +56,7 @@
   ASSERT(input1);
 
   FilterEffect* effect = FETile::create(filter);
-  effect->inputEffects().append(input1);
+  effect->inputEffects().push_back(input1);
   return effect;
 }
 
diff --git a/third_party/WebKit/Source/core/svg/SVGFETurbulenceElement.cpp b/third_party/WebKit/Source/core/svg/SVGFETurbulenceElement.cpp
index 48a82b0..bf2c5f9 100644
--- a/third_party/WebKit/Source/core/svg/SVGFETurbulenceElement.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGFETurbulenceElement.cpp
@@ -28,8 +28,8 @@
 const SVGEnumerationStringEntries& getStaticStringEntries<SVGStitchOptions>() {
   DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
   if (entries.isEmpty()) {
-    entries.append(std::make_pair(kSvgStitchtypeStitch, "stitch"));
-    entries.append(std::make_pair(kSvgStitchtypeNostitch, "noStitch"));
+    entries.push_back(std::make_pair(kSvgStitchtypeStitch, "stitch"));
+    entries.push_back(std::make_pair(kSvgStitchtypeNostitch, "noStitch"));
   }
   return entries;
 }
@@ -38,9 +38,10 @@
 const SVGEnumerationStringEntries& getStaticStringEntries<TurbulenceType>() {
   DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
   if (entries.isEmpty()) {
-    entries.append(
+    entries.push_back(
         std::make_pair(FETURBULENCE_TYPE_FRACTALNOISE, "fractalNoise"));
-    entries.append(std::make_pair(FETURBULENCE_TYPE_TURBULENCE, "turbulence"));
+    entries.push_back(
+        std::make_pair(FETURBULENCE_TYPE_TURBULENCE, "turbulence"));
   }
   return entries;
 }
diff --git a/third_party/WebKit/Source/core/svg/SVGGradientElement.cpp b/third_party/WebKit/Source/core/svg/SVGGradientElement.cpp
index a2954ad..74edf376 100644
--- a/third_party/WebKit/Source/core/svg/SVGGradientElement.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGGradientElement.cpp
@@ -35,9 +35,9 @@
 getStaticStringEntries<SVGSpreadMethodType>() {
   DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
   if (entries.isEmpty()) {
-    entries.append(std::make_pair(SVGSpreadMethodPad, "pad"));
-    entries.append(std::make_pair(SVGSpreadMethodReflect, "reflect"));
-    entries.append(std::make_pair(SVGSpreadMethodRepeat, "repeat"));
+    entries.push_back(std::make_pair(SVGSpreadMethodPad, "pad"));
+    entries.push_back(std::make_pair(SVGSpreadMethodReflect, "reflect"));
+    entries.push_back(std::make_pair(SVGSpreadMethodRepeat, "repeat"));
   }
   return entries;
 }
@@ -130,7 +130,8 @@
     offset = std::min(std::max(previousOffset, offset), 1.0f);
     previousOffset = offset;
 
-    stops.append(Gradient::ColorStop(offset, stop.stopColorIncludingOpacity()));
+    stops.push_back(
+        Gradient::ColorStop(offset, stop.stopColorIncludingOpacity()));
   }
   return stops;
 }
diff --git a/third_party/WebKit/Source/core/svg/SVGMarkerElement.cpp b/third_party/WebKit/Source/core/svg/SVGMarkerElement.cpp
index 06e7d146..ff874a5 100644
--- a/third_party/WebKit/Source/core/svg/SVGMarkerElement.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGMarkerElement.cpp
@@ -33,9 +33,9 @@
 getStaticStringEntries<SVGMarkerUnitsType>() {
   DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
   if (entries.isEmpty()) {
-    entries.append(
+    entries.push_back(
         std::make_pair(SVGMarkerUnitsUserSpaceOnUse, "userSpaceOnUse"));
-    entries.append(std::make_pair(SVGMarkerUnitsStrokeWidth, "strokeWidth"));
+    entries.push_back(std::make_pair(SVGMarkerUnitsStrokeWidth, "strokeWidth"));
   }
   return entries;
 }
diff --git a/third_party/WebKit/Source/core/svg/SVGSVGElement.cpp b/third_party/WebKit/Source/core/svg/SVGSVGElement.cpp
index 1a81386..1432874 100644
--- a/third_party/WebKit/Source/core/svg/SVGSVGElement.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGSVGElement.cpp
@@ -368,7 +368,7 @@
   for (SVGGraphicsElement& element :
        Traversal<SVGGraphicsElement>::descendantsOf(*root)) {
     if (checkIntersectionOrEnclosure(element, rect, mode))
-      nodes.append(&element);
+      nodes.push_back(&element);
   }
 
   return StaticNodeList::adopt(nodes);
diff --git a/third_party/WebKit/Source/core/svg/SVGStringList.cpp b/third_party/WebKit/Source/core/svg/SVGStringList.cpp
index c726a3f..be9c878d 100644
--- a/third_party/WebKit/Source/core/svg/SVGStringList.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGStringList.cpp
@@ -35,7 +35,7 @@
 
 void SVGStringList::initialize(const String& item) {
   m_values.clear();
-  m_values.append(item);
+  m_values.push_back(item);
 }
 
 String SVGStringList::getItem(size_t index, ExceptionState& exceptionState) {
@@ -68,7 +68,7 @@
 }
 
 void SVGStringList::appendItem(const String& newItem) {
-  m_values.append(newItem);
+  m_values.push_back(newItem);
 }
 
 void SVGStringList::replaceItem(const String& newItem,
@@ -91,7 +91,7 @@
       ptr++;
     if (ptr == start)
       break;
-    m_values.append(String(start, ptr - start));
+    m_values.push_back(String(start, ptr - start));
     skipOptionalSVGSpacesOrDelimiter(ptr, end, delimiter);
   }
 }
diff --git a/third_party/WebKit/Source/core/svg/SVGTextContentElement.cpp b/third_party/WebKit/Source/core/svg/SVGTextContentElement.cpp
index 150bfa2..aca2e19 100644
--- a/third_party/WebKit/Source/core/svg/SVGTextContentElement.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGTextContentElement.cpp
@@ -41,8 +41,8 @@
 getStaticStringEntries<SVGLengthAdjustType>() {
   DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
   if (entries.isEmpty()) {
-    entries.append(std::make_pair(SVGLengthAdjustSpacing, "spacing"));
-    entries.append(
+    entries.push_back(std::make_pair(SVGLengthAdjustSpacing, "spacing"));
+    entries.push_back(
         std::make_pair(SVGLengthAdjustSpacingAndGlyphs, "spacingAndGlyphs"));
   }
   return entries;
diff --git a/third_party/WebKit/Source/core/svg/SVGTextPathElement.cpp b/third_party/WebKit/Source/core/svg/SVGTextPathElement.cpp
index 12b7eaa0..eae5a2b 100644
--- a/third_party/WebKit/Source/core/svg/SVGTextPathElement.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGTextPathElement.cpp
@@ -30,8 +30,8 @@
 getStaticStringEntries<SVGTextPathMethodType>() {
   DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
   if (entries.isEmpty()) {
-    entries.append(std::make_pair(SVGTextPathMethodAlign, "align"));
-    entries.append(std::make_pair(SVGTextPathMethodStretch, "stretch"));
+    entries.push_back(std::make_pair(SVGTextPathMethodAlign, "align"));
+    entries.push_back(std::make_pair(SVGTextPathMethodStretch, "stretch"));
   }
   return entries;
 }
@@ -41,8 +41,8 @@
 getStaticStringEntries<SVGTextPathSpacingType>() {
   DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
   if (entries.isEmpty()) {
-    entries.append(std::make_pair(SVGTextPathSpacingAuto, "auto"));
-    entries.append(std::make_pair(SVGTextPathSpacingExact, "exact"));
+    entries.push_back(std::make_pair(SVGTextPathSpacingAuto, "auto"));
+    entries.push_back(std::make_pair(SVGTextPathSpacingExact, "exact"));
   }
   return entries;
 }
diff --git a/third_party/WebKit/Source/core/svg/SVGTransformList.cpp b/third_party/WebKit/Source/core/svg/SVGTransformList.cpp
index 1ea79f1..016cf90f 100644
--- a/third_party/WebKit/Source/core/svg/SVGTransformList.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGTransformList.cpp
@@ -232,7 +232,7 @@
     if (!parseNumber(ptr, end, argumentValue, AllowLeadingWhitespace))
       break;
 
-    arguments.append(argumentValue);
+    arguments.push_back(argumentValue);
     trailingDelimiter = false;
 
     if (arguments.size() == requiredWithOptional)
diff --git a/third_party/WebKit/Source/core/svg/SVGUnitTypes.cpp b/third_party/WebKit/Source/core/svg/SVGUnitTypes.cpp
index e57414b..be605f32 100644
--- a/third_party/WebKit/Source/core/svg/SVGUnitTypes.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGUnitTypes.cpp
@@ -37,10 +37,10 @@
 getStaticStringEntries<SVGUnitTypes::SVGUnitType>() {
   DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
   if (entries.isEmpty()) {
-    entries.append(std::make_pair(SVGUnitTypes::kSvgUnitTypeUserspaceonuse,
-                                  "userSpaceOnUse"));
-    entries.append(std::make_pair(SVGUnitTypes::kSvgUnitTypeObjectboundingbox,
-                                  "objectBoundingBox"));
+    entries.push_back(std::make_pair(SVGUnitTypes::kSvgUnitTypeUserspaceonuse,
+                                     "userSpaceOnUse"));
+    entries.push_back(std::make_pair(
+        SVGUnitTypes::kSvgUnitTypeObjectboundingbox, "objectBoundingBox"));
   }
   return entries;
 }
diff --git a/third_party/WebKit/Source/core/svg/UnsafeSVGAttributeSanitizationTest.cpp b/third_party/WebKit/Source/core/svg/UnsafeSVGAttributeSanitizationTest.cpp
index 1917b43..d2c68ce 100644
--- a/third_party/WebKit/Source/core/svg/UnsafeSVGAttributeSanitizationTest.cpp
+++ b/third_party/WebKit/Source/core/svg/UnsafeSVGAttributeSanitizationTest.cpp
@@ -287,10 +287,10 @@
 TEST(UnsafeSVGAttributeSanitizationTest,
      stripScriptingAttributes_animateElement) {
   Vector<Attribute> attributes;
-  attributes.append(Attribute(XLinkNames::hrefAttr, "javascript:alert()"));
-  attributes.append(Attribute(SVGNames::hrefAttr, "javascript:alert()"));
-  attributes.append(Attribute(SVGNames::fromAttr, "/home"));
-  attributes.append(Attribute(SVGNames::toAttr, "javascript:own3d()"));
+  attributes.push_back(Attribute(XLinkNames::hrefAttr, "javascript:alert()"));
+  attributes.push_back(Attribute(SVGNames::hrefAttr, "javascript:alert()"));
+  attributes.push_back(Attribute(SVGNames::fromAttr, "/home"));
+  attributes.push_back(Attribute(SVGNames::toAttr, "javascript:own3d()"));
 
   Document* document = Document::create();
   Element* element = SVGAnimateElement::create(*document);
diff --git a/third_party/WebKit/Source/core/svg/animation/SMILTimeContainer.cpp b/third_party/WebKit/Source/core/svg/animation/SMILTimeContainer.cpp
index 66231b43..a9b1b9a 100644
--- a/third_party/WebKit/Source/core/svg/animation/SMILTimeContainer.cpp
+++ b/third_party/WebKit/Source/core/svg/animation/SMILTimeContainer.cpp
@@ -461,7 +461,7 @@
       // This will calculate the contribution from the animation and update
       // timing.
       if (animation->progress(elapsed, seekToTime)) {
-        sandwich.append(animation);
+        sandwich.push_back(animation);
       } else {
         animation->clearAnimatedType();
       }
@@ -485,7 +485,7 @@
       for (const auto& animation : sandwich)
         animation->updateAnimatedValue(resultElement);
 
-      animationsToApply.append(resultElement);
+      animationsToApply.push_back(resultElement);
     }
   }
   m_scheduledAnimations.removeAll(invalidKeys);
diff --git a/third_party/WebKit/Source/core/svg/animation/SVGSMILElement.cpp b/third_party/WebKit/Source/core/svg/animation/SVGSMILElement.cpp
index 674fd6f..c4a3b67 100644
--- a/third_party/WebKit/Source/core/svg/animation/SVGSMILElement.cpp
+++ b/third_party/WebKit/Source/core/svg/animation/SVGSMILElement.cpp
@@ -268,7 +268,7 @@
   // "If no attribute is present, the default begin value (an offset-value of 0)
   // must be evaluated."
   if (!fastHasAttribute(SVGNames::beginAttr))
-    m_beginTimes.append(SMILTimeWithOrigin());
+    m_beginTimes.push_back(SMILTimeWithOrigin());
 
   if (m_isWaitingForFirstInterval)
     resolveFirstInterval();
@@ -412,7 +412,7 @@
     type = Condition::EventBase;
   }
 
-  m_conditions.append(
+  m_conditions.push_back(
       Condition::create(type, beginOrEnd, baseID, nameString, offset, repeat));
 
   if (type == Condition::EventBase && beginOrEnd == End)
@@ -439,7 +439,7 @@
     if (value.isUnresolved())
       parseCondition(splitString[n], beginOrEnd);
     else if (!existing.contains(value.value()))
-      timeList.append(
+      timeList.push_back(
           SMILTimeWithOrigin(value, SMILTimeWithOrigin::ParserOrigin));
   }
   sortTimeList(timeList);
@@ -714,7 +714,7 @@
 void SVGSMILElement::addBeginTime(SMILTime eventTime,
                                   SMILTime beginTime,
                                   SMILTimeWithOrigin::Origin origin) {
-  m_beginTimes.append(SMILTimeWithOrigin(beginTime, origin));
+  m_beginTimes.push_back(SMILTimeWithOrigin(beginTime, origin));
   sortTimeList(m_beginTimes);
   beginListChanged(eventTime);
 }
@@ -722,7 +722,7 @@
 void SVGSMILElement::addEndTime(SMILTime eventTime,
                                 SMILTime endTime,
                                 SMILTimeWithOrigin::Origin origin) {
-  m_endTimes.append(SMILTimeWithOrigin(endTime, origin));
+  m_endTimes.push_back(SMILTimeWithOrigin(endTime, origin));
   sortTimeList(m_endTimes);
   endListChanged(eventTime);
 }
@@ -1250,7 +1250,7 @@
 }
 
 void SVGSMILElement::scheduleRepeatEvents(unsigned count) {
-  m_repeatEventCountList.append(count);
+  m_repeatEventCountList.push_back(count);
   scheduleEvent(EventTypeNames::repeatEvent);
   scheduleEvent(AtomicString("repeatn"));
 }
diff --git a/third_party/WebKit/Source/core/svg/properties/SVGListPropertyHelper.h b/third_party/WebKit/Source/core/svg/properties/SVGListPropertyHelper.h
index 7bf4130..2bea7c4b67 100644
--- a/third_party/WebKit/Source/core/svg/properties/SVGListPropertyHelper.h
+++ b/third_party/WebKit/Source/core/svg/properties/SVGListPropertyHelper.h
@@ -100,7 +100,7 @@
 
   void append(ItemPropertyType* newItem) {
     ASSERT(newItem);
-    m_values.append(newItem);
+    m_values.push_back(newItem);
     newItem->setOwnerList(this);
   }
 
diff --git a/third_party/WebKit/Source/core/testing/DeathAwareScriptWrappable.h b/third_party/WebKit/Source/core/testing/DeathAwareScriptWrappable.h
index ff3b204..ee3e835d 100644
--- a/third_party/WebKit/Source/core/testing/DeathAwareScriptWrappable.h
+++ b/third_party/WebKit/Source/core/testing/DeathAwareScriptWrappable.h
@@ -66,7 +66,7 @@
   }
 
   void addWrappedVectorDependency(DeathAwareScriptWrappable* dependency) {
-    m_wrappedVectorDependency.append(Wrapper(this, dependency));
+    m_wrappedVectorDependency.push_back(Wrapper(this, dependency));
   }
 
   void addWrappedHashMapDependency(DeathAwareScriptWrappable* key,
diff --git a/third_party/WebKit/Source/core/testing/DictionaryTest.cpp b/third_party/WebKit/Source/core/testing/DictionaryTest.cpp
index 3535596..07dea6b73 100644
--- a/third_party/WebKit/Source/core/testing/DictionaryTest.cpp
+++ b/third_party/WebKit/Source/core/testing/DictionaryTest.cpp
@@ -4,6 +4,7 @@
 
 #include "core/testing/DictionaryTest.h"
 
+#include "bindings/core/v8/ScriptState.h"
 #include "bindings/core/v8/V8ObjectBuilder.h"
 #include "core/testing/InternalDictionary.h"
 #include "core/testing/InternalDictionaryDerived.h"
@@ -165,10 +166,11 @@
 }
 
 String DictionaryTest::stringFromIterable(
-    ExecutionContext* executionContext,
+    ScriptState* scriptState,
     Dictionary iterable,
     ExceptionState& exceptionState) const {
   StringBuilder result;
+  ExecutionContext* executionContext = scriptState->getExecutionContext();
   DictionaryIterator iterator = iterable.getIterator(executionContext);
   if (iterator.isNull())
     return emptyString();
diff --git a/third_party/WebKit/Source/core/testing/DictionaryTest.h b/third_party/WebKit/Source/core/testing/DictionaryTest.h
index a0fcd0b..9df16d67 100644
--- a/third_party/WebKit/Source/core/testing/DictionaryTest.h
+++ b/third_party/WebKit/Source/core/testing/DictionaryTest.h
@@ -7,7 +7,6 @@
 
 #include "bindings/core/v8/DoubleOrString.h"
 #include "bindings/core/v8/Nullable.h"
-#include "bindings/core/v8/ScriptState.h"
 #include "bindings/core/v8/ScriptValue.h"
 #include "bindings/core/v8/ScriptWrappable.h"
 #include "core/dom/Element.h"
@@ -20,6 +19,7 @@
 class InternalDictionary;
 class InternalDictionaryDerived;
 class InternalDictionaryDerivedDerived;
+class ScriptState;
 
 class DictionaryTest : public GarbageCollectedFinalized<DictionaryTest>,
                        public ScriptWrappable {
@@ -43,7 +43,7 @@
   void setDerivedDerived(const InternalDictionaryDerivedDerived&);
   void getDerivedDerived(InternalDictionaryDerivedDerived&);
 
-  String stringFromIterable(ExecutionContext*,
+  String stringFromIterable(ScriptState*,
                             Dictionary iterable,
                             ExceptionState&) const;
 
diff --git a/third_party/WebKit/Source/core/testing/DictionaryTest.idl b/third_party/WebKit/Source/core/testing/DictionaryTest.idl
index d244022a..e1cddf7c 100644
--- a/third_party/WebKit/Source/core/testing/DictionaryTest.idl
+++ b/third_party/WebKit/Source/core/testing/DictionaryTest.idl
@@ -13,5 +13,5 @@
     void setDerivedDerived(InternalDictionaryDerivedDerived derived);
     InternalDictionaryDerivedDerived getDerivedDerived();
 
-    [CallWith=ExecutionContext, RaisesException] DOMString stringFromIterable(Dictionary iterableDictionary);
+    [CallWith=ScriptState, RaisesException] DOMString stringFromIterable(Dictionary iterableDictionary);
 };
diff --git a/third_party/WebKit/Source/core/testing/Internals.cpp b/third_party/WebKit/Source/core/testing/Internals.cpp
index fb62a43..faf7bfe 100644
--- a/third_party/WebKit/Source/core/testing/Internals.cpp
+++ b/third_party/WebKit/Source/core/testing/Internals.cpp
@@ -1477,7 +1477,7 @@
 void Internals::setUserPreferredLanguages(const Vector<String>& languages) {
   Vector<AtomicString> atomicLanguages;
   for (size_t i = 0; i < languages.size(); ++i)
-    atomicLanguages.append(AtomicString(languages[i]));
+    atomicLanguages.push_back(AtomicString(languages[i]));
   overrideUserPreferredLanguages(atomicLanguages);
 }
 
@@ -2127,7 +2127,7 @@
   Vector<String> array;
 
   for (auto& iconURL : iconURLs)
-    array.append(iconURL.m_iconURL.getString());
+    array.push_back(iconURL.m_iconURL.getString());
 
   return array;
 }
@@ -2440,7 +2440,7 @@
   Vector<FloatQuad> quads;
   for (size_t i = 0; i < regions.size(); ++i) {
     if (regions[i].draggable == draggable)
-      quads.append(FloatQuad(FloatRect(regions[i].bounds)));
+      quads.push_back(FloatQuad(FloatRect(regions[i].bounds)));
   }
   return ClientRectList::create(quads);
 }
diff --git a/third_party/WebKit/Source/core/testing/LayerRectList.cpp b/third_party/WebKit/Source/core/testing/LayerRectList.cpp
index f128f529..1dff9105 100644
--- a/third_party/WebKit/Source/core/testing/LayerRectList.cpp
+++ b/third_party/WebKit/Source/core/testing/LayerRectList.cpp
@@ -54,8 +54,8 @@
                            int layerOffsetX,
                            int layerOffsetY,
                            ClientRect* layerRelativeRect) {
-  m_list.append(LayerRect::create(layerRootNode, layerType, layerOffsetX,
-                                  layerOffsetY, layerRelativeRect));
+  m_list.push_back(LayerRect::create(layerRootNode, layerType, layerOffsetX,
+                                     layerOffsetY, layerRelativeRect));
 }
 
 DEFINE_TRACE(LayerRectList) {
diff --git a/third_party/WebKit/Source/core/timing/PerformanceBase.cpp b/third_party/WebKit/Source/core/timing/PerformanceBase.cpp
index 660507e..78da775 100644
--- a/third_party/WebKit/Source/core/timing/PerformanceBase.cpp
+++ b/third_party/WebKit/Source/core/timing/PerformanceBase.cpp
@@ -113,7 +113,7 @@
 
   entries.appendVector(m_resourceTimingBuffer);
   if (m_navigationTiming)
-    entries.append(m_navigationTiming);
+    entries.push_back(m_navigationTiming);
   entries.appendVector(m_frameTimingBuffer);
 
   if (m_userTiming) {
@@ -135,17 +135,17 @@
   switch (type) {
     case PerformanceEntry::Resource:
       for (const auto& resource : m_resourceTimingBuffer)
-        entries.append(resource);
+        entries.push_back(resource);
       break;
     case PerformanceEntry::Navigation:
       if (m_navigationTiming)
-        entries.append(m_navigationTiming);
+        entries.push_back(m_navigationTiming);
       break;
     case PerformanceEntry::Composite:
     case PerformanceEntry::Render:
       for (const auto& frame : m_frameTimingBuffer) {
         if (type == frame->entryTypeEnum()) {
-          entries.append(frame);
+          entries.push_back(frame);
         }
       }
       break;
@@ -186,13 +186,13 @@
   if (entryType.isNull() || type == PerformanceEntry::Resource) {
     for (const auto& resource : m_resourceTimingBuffer) {
       if (resource->name() == name)
-        entries.append(resource);
+        entries.push_back(resource);
     }
   }
 
   if (entryType.isNull() || type == PerformanceEntry::Navigation) {
     if (m_navigationTiming && m_navigationTiming->name() == name)
-      entries.append(m_navigationTiming);
+      entries.push_back(m_navigationTiming);
   }
 
   if (entryType.isNull() || type == PerformanceEntry::Composite ||
@@ -200,7 +200,7 @@
     for (const auto& frame : m_frameTimingBuffer) {
       if (frame->name() == name &&
           (entryType.isNull() || entryType == frame->entryType()))
-        entries.append(frame);
+        entries.push_back(frame);
     }
   }
 
@@ -404,7 +404,7 @@
 }
 
 void PerformanceBase::addResourceTimingBuffer(PerformanceEntry& entry) {
-  m_resourceTimingBuffer.append(&entry);
+  m_resourceTimingBuffer.push_back(&entry);
 
   if (isResourceTimingBufferFull()) {
     dispatchEvent(Event::create(EventTypeNames::resourcetimingbufferfull));
@@ -418,7 +418,7 @@
 }
 
 void PerformanceBase::addFrameTimingBuffer(PerformanceEntry& entry) {
-  m_frameTimingBuffer.append(&entry);
+  m_frameTimingBuffer.push_back(&entry);
 
   if (isFrameTimingBufferFull())
     dispatchEvent(Event::create(EventTypeNames::frametimingbufferfull));
diff --git a/third_party/WebKit/Source/core/timing/PerformanceBaseTest.cpp b/third_party/WebKit/Source/core/timing/PerformanceBaseTest.cpp
index 08ae8d8..78ac999 100644
--- a/third_party/WebKit/Source/core/timing/PerformanceBaseTest.cpp
+++ b/third_party/WebKit/Source/core/timing/PerformanceBaseTest.cpp
@@ -129,7 +129,7 @@
   NonThrowableExceptionState exceptionState;
   PerformanceObserverInit options;
   Vector<String> entryTypeVec;
-  entryTypeVec.append("longtask");
+  entryTypeVec.push_back("longtask");
   options.setEntryTypes(entryTypeVec);
   m_observer->observe(options, exceptionState);
 
@@ -171,8 +171,8 @@
   redirectResponse1.setURL(url);
   ResourceResponse redirectResponse2;
   redirectResponse2.setURL(url);
-  redirectChain.append(redirectResponse1);
-  redirectChain.append(redirectResponse2);
+  redirectChain.push_back(redirectResponse1);
+  redirectChain.push_back(redirectResponse2);
   RefPtr<SecurityOrigin> securityOrigin = SecurityOrigin::create(url);
   EXPECT_TRUE(allowsTimingRedirect(redirectChain, finalResponse,
                                    *securityOrigin.get(),
@@ -182,7 +182,7 @@
   KURL redirectUrl(ParsedURLString, crossOriginDomain + "/bar.html");
   ResourceResponse redirectResponse3;
   redirectResponse3.setURL(redirectUrl);
-  redirectChain.append(redirectResponse3);
+  redirectChain.push_back(redirectResponse3);
   EXPECT_FALSE(allowsTimingRedirect(redirectChain, finalResponse,
                                     *securityOrigin.get(),
                                     getExecutionContext()));
diff --git a/third_party/WebKit/Source/core/timing/PerformanceLongTaskTiming.cpp b/third_party/WebKit/Source/core/timing/PerformanceLongTaskTiming.cpp
index 448b4780..63e1658 100644
--- a/third_party/WebKit/Source/core/timing/PerformanceLongTaskTiming.cpp
+++ b/third_party/WebKit/Source/core/timing/PerformanceLongTaskTiming.cpp
@@ -42,7 +42,7 @@
   // Only one possible name ("frame") currently.
   TaskAttributionTiming* attributionEntry = TaskAttributionTiming::create(
       "frame", culpritFrameSrc, culpritFrameId, culpritFrameName);
-  m_attribution.append(*attributionEntry);
+  m_attribution.push_back(*attributionEntry);
 }
 
 PerformanceLongTaskTiming::~PerformanceLongTaskTiming() {}
diff --git a/third_party/WebKit/Source/core/timing/PerformanceObserver.cpp b/third_party/WebKit/Source/core/timing/PerformanceObserver.cpp
index 27c6d2ca..6b258b61 100644
--- a/third_party/WebKit/Source/core/timing/PerformanceObserver.cpp
+++ b/third_party/WebKit/Source/core/timing/PerformanceObserver.cpp
@@ -71,7 +71,7 @@
 
 void PerformanceObserver::enqueuePerformanceEntry(PerformanceEntry& entry) {
   ASSERT(isMainThread());
-  m_performanceEntries.append(&entry);
+  m_performanceEntries.push_back(&entry);
   if (m_performance)
     m_performance->activateObserver(*this);
 }
diff --git a/third_party/WebKit/Source/core/timing/PerformanceObserverEntryList.cpp b/third_party/WebKit/Source/core/timing/PerformanceObserverEntryList.cpp
index d84771e..ccfe66f 100644
--- a/third_party/WebKit/Source/core/timing/PerformanceObserverEntryList.cpp
+++ b/third_party/WebKit/Source/core/timing/PerformanceObserverEntryList.cpp
@@ -37,7 +37,7 @@
 
   for (const auto& entry : m_performanceEntries) {
     if (entry->entryTypeEnum() == type) {
-      entries.append(entry);
+      entries.push_back(entry);
     }
   }
 
@@ -59,7 +59,7 @@
   for (const auto& entry : m_performanceEntries) {
     if (entry->name() == name &&
         (entryType.isNull() || type == entry->entryTypeEnum())) {
-      entries.append(entry);
+      entries.push_back(entry);
     }
   }
 
diff --git a/third_party/WebKit/Source/core/timing/PerformanceObserverTest.cpp b/third_party/WebKit/Source/core/timing/PerformanceObserverTest.cpp
index 16aa20c..8d6a66d 100644
--- a/third_party/WebKit/Source/core/timing/PerformanceObserverTest.cpp
+++ b/third_party/WebKit/Source/core/timing/PerformanceObserverTest.cpp
@@ -51,7 +51,7 @@
   NonThrowableExceptionState exceptionState;
   PerformanceObserverInit options;
   Vector<String> entryTypeVec;
-  entryTypeVec.append("mark");
+  entryTypeVec.push_back("mark");
   options.setEntryTypes(entryTypeVec);
 
   m_observer->observe(options, exceptionState);
diff --git a/third_party/WebKit/Source/core/timing/PerformanceUserTiming.cpp b/third_party/WebKit/Source/core/timing/PerformanceUserTiming.cpp
index 7ef949d..fcf0013 100644
--- a/third_party/WebKit/Source/core/timing/PerformanceUserTiming.cpp
+++ b/third_party/WebKit/Source/core/timing/PerformanceUserTiming.cpp
@@ -84,7 +84,7 @@
                                    PerformanceEntry& entry) {
   PerformanceEntryMap::iterator it = performanceEntryMap.find(entry.name());
   if (it != performanceEntryMap.end()) {
-    it->value.append(&entry);
+    it->value.push_back(&entry);
   } else {
     PerformanceEntryVector vector(1);
     vector[0] = Member<PerformanceEntry>(entry);
diff --git a/third_party/WebKit/Source/core/timing/SharedWorkerPerformance.cpp b/third_party/WebKit/Source/core/timing/SharedWorkerPerformance.cpp
index 4752e69..b25d2a3 100644
--- a/third_party/WebKit/Source/core/timing/SharedWorkerPerformance.cpp
+++ b/third_party/WebKit/Source/core/timing/SharedWorkerPerformance.cpp
@@ -29,6 +29,7 @@
 
 #include "core/timing/SharedWorkerPerformance.h"
 
+#include "bindings/core/v8/ScriptState.h"
 #include "core/dom/Document.h"
 #include "core/dom/ExecutionContext.h"
 #include "core/loader/DocumentLoadTiming.h"
@@ -55,10 +56,10 @@
   return *supplement;
 }
 
-double SharedWorkerPerformance::workerStart(ExecutionContext* context,
+double SharedWorkerPerformance::workerStart(ScriptState* scriptState,
                                             SharedWorker& sharedWorker) {
   return SharedWorkerPerformance::from(sharedWorker)
-      .getWorkerStart(context, sharedWorker);
+      .getWorkerStart(scriptState->getExecutionContext(), sharedWorker);
 }
 
 double SharedWorkerPerformance::getWorkerStart(ExecutionContext* context,
diff --git a/third_party/WebKit/Source/core/timing/SharedWorkerPerformance.h b/third_party/WebKit/Source/core/timing/SharedWorkerPerformance.h
index 10c37461..ebcb21c 100644
--- a/third_party/WebKit/Source/core/timing/SharedWorkerPerformance.h
+++ b/third_party/WebKit/Source/core/timing/SharedWorkerPerformance.h
@@ -36,7 +36,7 @@
 
 namespace blink {
 
-class ExecutionContext;
+class ScriptState;
 class SharedWorker;
 
 class SharedWorkerPerformance final
@@ -47,7 +47,7 @@
  public:
   static SharedWorkerPerformance& from(SharedWorker&);
 
-  static double workerStart(ExecutionContext*, SharedWorker&);
+  static double workerStart(ScriptState*, SharedWorker&);
   double getWorkerStart(ExecutionContext*, SharedWorker&) const;
 
   DEFINE_INLINE_VIRTUAL_TRACE() { Supplement<SharedWorker>::trace(visitor); }
diff --git a/third_party/WebKit/Source/core/timing/SharedWorkerPerformance.idl b/third_party/WebKit/Source/core/timing/SharedWorkerPerformance.idl
index eee0102c..2c958601 100644
--- a/third_party/WebKit/Source/core/timing/SharedWorkerPerformance.idl
+++ b/third_party/WebKit/Source/core/timing/SharedWorkerPerformance.idl
@@ -32,5 +32,5 @@
 // https://github.com/w3c/hr-time/commit/39aaf81e1ea206fdf0fde4f49604ddd64d4f5b13
 
 partial interface SharedWorker {
-    [CallWith=ExecutionContext, Measure] readonly attribute DOMHighResTimeStamp workerStart;
+    [CallWith=ScriptState, Measure] readonly attribute DOMHighResTimeStamp workerStart;
 };
diff --git a/third_party/WebKit/Source/core/workers/DedicatedWorkerTest.cpp b/third_party/WebKit/Source/core/workers/DedicatedWorkerTest.cpp
index 3c0fb97..dd82c0f 100644
--- a/third_party/WebKit/Source/core/workers/DedicatedWorkerTest.cpp
+++ b/third_party/WebKit/Source/core/workers/DedicatedWorkerTest.cpp
@@ -115,7 +115,7 @@
         WTF::makeUnique<Vector<CSPHeaderAndType>>();
     CSPHeaderAndType headerAndType("contentSecurityPolicy",
                                    ContentSecurityPolicyHeaderTypeReport);
-    headers->append(headerAndType);
+    headers->push_back(headerAndType);
     workerThread()->start(WorkerThreadStartupData::create(
         scriptURL, "fake user agent", source, nullptr /* cachedMetaData */,
         DontPauseWorkerGlobalScopeOnStart, headers.get(),
diff --git a/third_party/WebKit/Source/core/workers/InProcessWorkerMessagingProxy.cpp b/third_party/WebKit/Source/core/workers/InProcessWorkerMessagingProxy.cpp
index edf0372..6026c09 100644
--- a/third_party/WebKit/Source/core/workers/InProcessWorkerMessagingProxy.cpp
+++ b/third_party/WebKit/Source/core/workers/InProcessWorkerMessagingProxy.cpp
@@ -166,7 +166,7 @@
     ++m_unconfirmedMessageCount;
     workerThread()->postTask(BLINK_FROM_HERE, std::move(task));
   } else {
-    m_queuedEarlyTasks.append(std::move(task));
+    m_queuedEarlyTasks.push_back(std::move(task));
   }
 }
 
diff --git a/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp b/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp
index 4455c27..4ce3ed5 100644
--- a/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp
+++ b/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp
@@ -185,7 +185,7 @@
           "The script at '" + url.elidedString() + "' failed to load.");
       return;
     }
-    completedURLs.append(url);
+    completedURLs.push_back(url);
   }
 
   for (const KURL& completeURL : completedURLs) {
diff --git a/third_party/WebKit/Source/core/workers/WorkerThreadStartupData.cpp b/third_party/WebKit/Source/core/workers/WorkerThreadStartupData.cpp
index 336687a..b282527a 100644
--- a/third_party/WebKit/Source/core/workers/WorkerThreadStartupData.cpp
+++ b/third_party/WebKit/Source/core/workers/WorkerThreadStartupData.cpp
@@ -66,14 +66,14 @@
   if (contentSecurityPolicyHeaders) {
     for (const auto& header : *contentSecurityPolicyHeaders) {
       CSPHeaderAndType copiedHeader(header.first.isolatedCopy(), header.second);
-      m_contentSecurityPolicyHeaders->append(copiedHeader);
+      m_contentSecurityPolicyHeaders->push_back(copiedHeader);
     }
   }
 
   m_originTrialTokens = std::unique_ptr<Vector<String>>(new Vector<String>());
   if (originTrialTokens) {
     for (const String& token : *originTrialTokens)
-      m_originTrialTokens->append(token.isolatedCopy());
+      m_originTrialTokens->push_back(token.isolatedCopy());
   }
 }
 
diff --git a/third_party/WebKit/Source/core/workers/WorkerThreadTest.cpp b/third_party/WebKit/Source/core/workers/WorkerThreadTest.cpp
index 49426f4..1cffd5c 100644
--- a/third_party/WebKit/Source/core/workers/WorkerThreadTest.cpp
+++ b/third_party/WebKit/Source/core/workers/WorkerThreadTest.cpp
@@ -270,7 +270,7 @@
       WTF::makeUnique<Vector<CSPHeaderAndType>>();
   CSPHeaderAndType headerAndType("contentSecurityPolicy",
                                  ContentSecurityPolicyHeaderTypeReport);
-  headers->append(headerAndType);
+  headers->push_back(headerAndType);
 
   // Specify PauseWorkerGlobalScopeOnStart so that the worker thread can pause
   // on initialziation to run debugger tasks.
diff --git a/third_party/WebKit/Source/core/workers/WorkerThreadTestHelper.h b/third_party/WebKit/Source/core/workers/WorkerThreadTestHelper.h
index c77f838..c0b3849 100644
--- a/third_party/WebKit/Source/core/workers/WorkerThreadTestHelper.h
+++ b/third_party/WebKit/Source/core/workers/WorkerThreadTestHelper.h
@@ -141,7 +141,7 @@
         WTF::makeUnique<Vector<CSPHeaderAndType>>();
     CSPHeaderAndType headerAndType("contentSecurityPolicy",
                                    ContentSecurityPolicyHeaderTypeReport);
-    headers->append(headerAndType);
+    headers->push_back(headerAndType);
 
     WorkerClients* clients = nullptr;
 
diff --git a/third_party/WebKit/Source/core/xml/DocumentXMLTreeViewer.cpp b/third_party/WebKit/Source/core/xml/DocumentXMLTreeViewer.cpp
index 56967b2..65d73f6 100644
--- a/third_party/WebKit/Source/core/xml/DocumentXMLTreeViewer.cpp
+++ b/third_party/WebKit/Source/core/xml/DocumentXMLTreeViewer.cpp
@@ -20,7 +20,7 @@
   String cssString = loadResourceAsASCIIString("DocumentXMLTreeViewer.css");
 
   HeapVector<ScriptSourceCode> sources;
-  sources.append(ScriptSourceCode(scriptString));
+  sources.push_back(ScriptSourceCode(scriptString));
   v8::HandleScope handleScope(V8PerIsolateData::mainThreadIsolate());
 
   document.frame()->script().executeScriptInIsolatedWorld(
diff --git a/third_party/WebKit/Source/core/xml/XPathExpressionNode.h b/third_party/WebKit/Source/core/xml/XPathExpressionNode.h
index acb4dd5..5892c29 100644
--- a/third_party/WebKit/Source/core/xml/XPathExpressionNode.h
+++ b/third_party/WebKit/Source/core/xml/XPathExpressionNode.h
@@ -72,7 +72,7 @@
     m_isContextNodeSensitive |= expr->m_isContextNodeSensitive;
     m_isContextPositionSensitive |= expr->m_isContextPositionSensitive;
     m_isContextSizeSensitive |= expr->m_isContextSizeSensitive;
-    m_subExpressions.append(expr);
+    m_subExpressions.push_back(expr);
   }
 
   bool isContextNodeSensitive() const { return m_isContextNodeSensitive; }
diff --git a/third_party/WebKit/Source/core/xml/XPathFunctionsTest.cpp b/third_party/WebKit/Source/core/xml/XPathFunctionsTest.cpp
index 18b6e88..ef59c27 100644
--- a/third_party/WebKit/Source/core/xml/XPathFunctionsTest.cpp
+++ b/third_party/WebKit/Source/core/xml/XPathFunctionsTest.cpp
@@ -44,16 +44,16 @@
 
 static String substring(const char* string, double pos) {
   XPathArguments args;
-  args.append(new XPath::StringExpression(string));
-  args.append(new XPath::Number(pos));
+  args.push_back(new XPath::StringExpression(string));
+  args.push_back(new XPath::Number(pos));
   return substring(args);
 }
 
 static String substring(const char* string, double pos, double len) {
   XPathArguments args;
-  args.append(new XPath::StringExpression(string));
-  args.append(new XPath::Number(pos));
-  args.append(new XPath::Number(len));
+  args.push_back(new XPath::StringExpression(string));
+  args.push_back(new XPath::Number(pos));
+  args.push_back(new XPath::Number(len));
   return substring(args);
 }
 
diff --git a/third_party/WebKit/Source/core/xml/XPathNodeSet.cpp b/third_party/WebKit/Source/core/xml/XPathNodeSet.cpp
index 2280112..e0995346 100644
--- a/third_party/WebKit/Source/core/xml/XPathNodeSet.cpp
+++ b/third_party/WebKit/Source/core/xml/XPathNodeSet.cpp
@@ -176,14 +176,14 @@
   for (unsigned i = 0; i < nodeCount; ++i) {
     NodeSetVector& parentsVector = parentMatrix[i];
     Node* n = m_nodes[i].get();
-    parentsVector.append(n);
+    parentsVector.push_back(n);
     if (n->isAttributeNode()) {
       n = toAttr(n)->ownerElement();
-      parentsVector.append(n);
+      parentsVector.push_back(n);
       containsAttributeNodes = true;
     }
     for (n = n->parentNode(); n; n = n->parentNode())
-      parentsVector.append(n);
+      parentsVector.push_back(n);
   }
   sortBlock(0, nodeCount, parentMatrix, containsAttributeNodes);
 
@@ -192,7 +192,7 @@
   HeapVector<Member<Node>> sortedNodes;
   sortedNodes.reserveInitialCapacity(nodeCount);
   for (unsigned i = 0; i < nodeCount; ++i)
-    sortedNodes.append(parentMatrix[i][0]);
+    sortedNodes.push_back(parentMatrix[i][0]);
 
   const_cast<HeapVector<Member<Node>>&>(m_nodes).swap(sortedNodes);
 }
@@ -227,7 +227,7 @@
 
   for (Node& n : NodeTraversal::startsAt(*findRootNode(m_nodes.front()))) {
     if (nodes.contains(&n))
-      sortedNodes.append(&n);
+      sortedNodes.push_back(&n);
 
     if (!containsAttributeNodes || !n.isElementNode())
       continue;
@@ -237,7 +237,7 @@
     for (auto& attribute : attributes) {
       Attr* attr = element->attrIfExists(attribute.name());
       if (attr && nodes.contains(attr))
-        sortedNodes.append(attr);
+        sortedNodes.push_back(attr);
     }
   }
 
diff --git a/third_party/WebKit/Source/core/xml/XPathNodeSet.h b/third_party/WebKit/Source/core/xml/XPathNodeSet.h
index 6ba8ee1..5ec9d77 100644
--- a/third_party/WebKit/Source/core/xml/XPathNodeSet.h
+++ b/third_party/WebKit/Source/core/xml/XPathNodeSet.h
@@ -60,7 +60,7 @@
   }
 
   // NodeSet itself does not verify that nodes in it are unique.
-  void append(Node* node) { m_nodes.append(node); }
+  void append(Node* node) { m_nodes.push_back(node); }
   void append(const NodeSet& nodeSet) { m_nodes.appendVector(nodeSet.m_nodes); }
 
   // Returns the set's first node in document order, or 0 if the set is empty.
diff --git a/third_party/WebKit/Source/core/xml/XPathPath.cpp b/third_party/WebKit/Source/core/xml/XPathPath.cpp
index f5eb17a..52cd1f95a 100644
--- a/third_party/WebKit/Source/core/xml/XPathPath.cpp
+++ b/third_party/WebKit/Source/core/xml/XPathPath.cpp
@@ -161,7 +161,7 @@
   if (stepCount && optimizeStepPair(m_steps[stepCount - 1], step))
     return;
   step->optimize();
-  m_steps.append(step);
+  m_steps.push_back(step);
 }
 
 void LocationPath::insertFirstStep(Step* step) {
diff --git a/third_party/WebKit/Source/core/xml/XPathStep.cpp b/third_party/WebKit/Source/core/xml/XPathStep.cpp
index 3872240..b9c8d6ab 100644
--- a/third_party/WebKit/Source/core/xml/XPathStep.cpp
+++ b/third_party/WebKit/Source/core/xml/XPathStep.cpp
@@ -69,9 +69,9 @@
     if ((!predicate->isContextPositionSensitive() ||
          nodeTest().mergedPredicates().isEmpty()) &&
         !predicate->isContextSizeSensitive() && remainingPredicates.isEmpty()) {
-      nodeTest().mergedPredicates().append(predicate);
+      nodeTest().mergedPredicates().push_back(predicate);
     } else {
-      remainingPredicates.append(predicate);
+      remainingPredicates.push_back(predicate);
     }
   }
   swap(remainingPredicates, m_predicates);
diff --git a/third_party/WebKit/Source/core/xml/XSLStyleSheetLibxslt.cpp b/third_party/WebKit/Source/core/xml/XSLStyleSheetLibxslt.cpp
index f5f240e..e9c2d48 100644
--- a/third_party/WebKit/Source/core/xml/XSLStyleSheetLibxslt.cpp
+++ b/third_party/WebKit/Source/core/xml/XSLStyleSheetLibxslt.cpp
@@ -223,7 +223,7 @@
 
 void XSLStyleSheet::loadChildSheet(const String& href) {
   XSLImportRule* childRule = XSLImportRule::create(this, href);
-  m_children.append(childRule);
+  m_children.push_back(childRule);
   childRule->loadSheet();
 }
 
diff --git a/third_party/WebKit/Source/core/xml/parser/XMLErrors.cpp b/third_party/WebKit/Source/core/xml/parser/XMLErrors.cpp
index 30755ef..4fcb54a 100644
--- a/third_party/WebKit/Source/core/xml/parser/XMLErrors.cpp
+++ b/third_party/WebKit/Source/core/xml/parser/XMLErrors.cpp
@@ -102,7 +102,7 @@
       CreatedByParser);
 
   Vector<Attribute> reportAttributes;
-  reportAttributes.append(Attribute(
+  reportAttributes.push_back(Attribute(
       styleAttr,
       "display: block; white-space: pre; border: 2px solid #c77; padding: 0 "
       "1em 0 1em; margin: 1em; background-color: #fdd; color: black"));
@@ -115,7 +115,7 @@
 
   Element* fixed = doc->createElement(divTag, CreatedByParser);
   Vector<Attribute> fixedAttributes;
-  fixedAttributes.append(
+  fixedAttributes.push_back(
       Attribute(styleAttr, "font-family:monospace;font-size:12px"));
   fixed->parserSetAttributes(fixedAttributes);
   reportElement->parserAppendChild(fixed);
@@ -170,7 +170,7 @@
 
   if (DocumentXSLT::hasTransformSourceDocument(*m_document)) {
     Vector<Attribute> attributes;
-    attributes.append(Attribute(styleAttr, "white-space: normal"));
+    attributes.push_back(Attribute(styleAttr, "white-space: normal"));
     Element* paragraph = m_document->createElement(pTag, CreatedByParser);
     paragraph->parserSetAttributes(attributes);
     paragraph->parserAppendChild(m_document->createTextNode(
diff --git a/third_party/WebKit/Source/modules/mediasession/MediaSession.idl b/third_party/WebKit/Source/modules/mediasession/MediaSession.idl
index c3d9ddd..aebfee9 100644
--- a/third_party/WebKit/Source/modules/mediasession/MediaSession.idl
+++ b/third_party/WebKit/Source/modules/mediasession/MediaSession.idl
@@ -26,7 +26,7 @@
 [
     Custom=VisitDOMWrapper,
     RuntimeEnabled=MediaSession,
-] interface MediaSession : EventTarget {
+] interface MediaSession {
     attribute MediaMetadata? metadata;
     attribute MediaSessionPlaybackState playbackState;
 
diff --git a/third_party/WebKit/Source/modules/mediasource/SourceBufferList.cpp b/third_party/WebKit/Source/modules/mediasource/SourceBufferList.cpp
index 535b694..e689f79 100644
--- a/third_party/WebKit/Source/modules/mediasource/SourceBufferList.cpp
+++ b/third_party/WebKit/Source/modules/mediasource/SourceBufferList.cpp
@@ -30,7 +30,6 @@
 
 #include "modules/mediasource/SourceBufferList.h"
 
-#include "core/dom/ExecutionContext.h"
 #include "core/events/GenericEventQueue.h"
 #include "modules/EventModules.h"
 #include "modules/mediasource/SourceBuffer.h"
@@ -39,7 +38,7 @@
 
 SourceBufferList::SourceBufferList(ExecutionContext* context,
                                    GenericEventQueue* asyncEventQueue)
-    : m_executionContext(context), m_asyncEventQueue(asyncEventQueue) {}
+    : ContextClient(context), m_asyncEventQueue(asyncEventQueue) {}
 
 SourceBufferList::~SourceBufferList() {}
 
@@ -79,15 +78,11 @@
   return EventTargetNames::SourceBufferList;
 }
 
-ExecutionContext* SourceBufferList::getExecutionContext() const {
-  return m_executionContext;
-}
-
 DEFINE_TRACE(SourceBufferList) {
-  visitor->trace(m_executionContext);
   visitor->trace(m_asyncEventQueue);
   visitor->trace(m_list);
   EventTargetWithInlineData::trace(visitor);
+  ContextClient::trace(visitor);
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/mediasource/SourceBufferList.h b/third_party/WebKit/Source/modules/mediasource/SourceBufferList.h
index 655814b..76d28d4 100644
--- a/third_party/WebKit/Source/modules/mediasource/SourceBufferList.h
+++ b/third_party/WebKit/Source/modules/mediasource/SourceBufferList.h
@@ -31,6 +31,7 @@
 #ifndef SourceBufferList_h
 #define SourceBufferList_h
 
+#include "core/dom/ExecutionContext.h"
 #include "modules/EventTargetModules.h"
 #include "platform/heap/Handle.h"
 
@@ -39,8 +40,10 @@
 class SourceBuffer;
 class GenericEventQueue;
 
-class SourceBufferList final : public EventTargetWithInlineData {
+class SourceBufferList final : public EventTargetWithInlineData,
+                               public ContextClient {
   DEFINE_WRAPPERTYPEINFO();
+  USING_GARBAGE_COLLECTED_MIXIN(SourceBufferList);
 
  public:
   static SourceBufferList* create(ExecutionContext* context,
@@ -69,7 +72,9 @@
 
   // EventTarget interface
   const AtomicString& interfaceName() const override;
-  ExecutionContext* getExecutionContext() const override;
+  ExecutionContext* getExecutionContext() const override {
+    return ContextClient::getExecutionContext();
+  }
 
   DECLARE_VIRTUAL_TRACE();
 
@@ -78,7 +83,6 @@
 
   void scheduleEvent(const AtomicString&);
 
-  Member<ExecutionContext> m_executionContext;
   Member<GenericEventQueue> m_asyncEventQueue;
 
   HeapVector<Member<SourceBuffer>> m_list;
diff --git a/third_party/WebKit/Source/modules/mediastream/MediaStream.cpp b/third_party/WebKit/Source/modules/mediastream/MediaStream.cpp
index ac17c67..57099921 100644
--- a/third_party/WebKit/Source/modules/mediastream/MediaStream.cpp
+++ b/third_party/WebKit/Source/modules/mediastream/MediaStream.cpp
@@ -96,9 +96,9 @@
 
 MediaStream::MediaStream(ExecutionContext* context,
                          MediaStreamDescriptor* streamDescriptor)
-    : m_descriptor(streamDescriptor),
-      m_scheduledEventTimer(this, &MediaStream::scheduledEventTimerFired),
-      m_executionContext(context) {
+    : ContextClient(context),
+      m_descriptor(streamDescriptor),
+      m_scheduledEventTimer(this, &MediaStream::scheduledEventTimerFired) {
   m_descriptor->setClient(this);
 
   size_t numberOfAudioTracks = m_descriptor->numberOfAudioComponents();
@@ -127,8 +127,8 @@
 MediaStream::MediaStream(ExecutionContext* context,
                          const MediaStreamTrackVector& audioTracks,
                          const MediaStreamTrackVector& videoTracks)
-    : m_scheduledEventTimer(this, &MediaStream::scheduledEventTimerFired),
-      m_executionContext(context) {
+    : ContextClient(context),
+      m_scheduledEventTimer(this, &MediaStream::scheduledEventTimerFired) {
   MediaStreamComponentVector audioComponents;
   MediaStreamComponentVector videoComponents;
 
@@ -295,7 +295,7 @@
 }
 
 void MediaStream::streamEnded() {
-  if (!m_executionContext || m_executionContext->isContextDestroyed())
+  if (!getExecutionContext())
     return;
 
   if (active()) {
@@ -309,9 +309,9 @@
     EventListener* listener,
     const AddEventListenerOptionsResolved& options) {
   if (eventType == EventTypeNames::active)
-    UseCounter::count(m_executionContext, UseCounter::MediaStreamOnActive);
+    UseCounter::count(getExecutionContext(), UseCounter::MediaStreamOnActive);
   else if (eventType == EventTypeNames::inactive)
-    UseCounter::count(m_executionContext, UseCounter::MediaStreamOnInactive);
+    UseCounter::count(getExecutionContext(), UseCounter::MediaStreamOnInactive);
 
   return EventTargetWithInlineData::addEventListenerInternal(eventType,
                                                              listener, options);
@@ -323,11 +323,11 @@
 
 void MediaStream::addRemoteTrack(MediaStreamComponent* component) {
   DCHECK(component);
-  if (!m_executionContext || m_executionContext->isContextDestroyed())
+  if (!getExecutionContext())
     return;
 
   MediaStreamTrack* track =
-      MediaStreamTrack::create(m_executionContext, component);
+      MediaStreamTrack::create(getExecutionContext(), component);
   switch (component->source()->type()) {
     case MediaStreamSource::TypeAudio:
       m_audioTracks.push_back(track);
@@ -350,7 +350,7 @@
 
 void MediaStream::removeRemoteTrack(MediaStreamComponent* component) {
   DCHECK(component);
-  if (!m_executionContext || m_executionContext->isContextDestroyed())
+  if (!getExecutionContext())
     return;
 
   MediaStreamTrackVector* tracks = 0;
@@ -395,7 +395,7 @@
 }
 
 void MediaStream::scheduledEventTimerFired(TimerBase*) {
-  if (!m_executionContext || m_executionContext->isContextDestroyed())
+  if (!getExecutionContext())
     return;
 
   HeapVector<Member<Event>> events;
@@ -417,8 +417,8 @@
   visitor->trace(m_videoTracks);
   visitor->trace(m_descriptor);
   visitor->trace(m_scheduledEvents);
-  visitor->trace(m_executionContext);
   EventTargetWithInlineData::trace(visitor);
+  ContextClient::trace(visitor);
   MediaStreamDescriptorClient::trace(visitor);
 }
 
diff --git a/third_party/WebKit/Source/modules/mediastream/MediaStream.h b/third_party/WebKit/Source/modules/mediastream/MediaStream.h
index d04cd2c..d6cf7bc 100644
--- a/third_party/WebKit/Source/modules/mediastream/MediaStream.h
+++ b/third_party/WebKit/Source/modules/mediastream/MediaStream.h
@@ -39,6 +39,7 @@
 class ExceptionState;
 
 class MODULES_EXPORT MediaStream final : public EventTargetWithInlineData,
+                                         public ContextClient,
                                          public URLRegistrable,
                                          public MediaStreamDescriptorClient {
   USING_GARBAGE_COLLECTED_MIXIN(MediaStream);
@@ -79,7 +80,7 @@
   // EventTarget
   const AtomicString& interfaceName() const override;
   ExecutionContext* getExecutionContext() const override {
-    return m_executionContext;
+    return ContextClient::getExecutionContext();
   }
 
   // URLRegistrable
@@ -114,10 +115,9 @@
 
   Timer<MediaStream> m_scheduledEventTimer;
   HeapVector<Member<Event>> m_scheduledEvents;
-  Member<ExecutionContext> m_executionContext;
 };
 
-typedef HeapVector<Member<MediaStream>> MediaStreamVector;
+using MediaStreamVector = HeapVector<Member<MediaStream>>;
 
 MediaStream* toMediaStream(MediaStreamDescriptor*);
 
diff --git a/third_party/WebKit/Source/modules/modules_idl_files.gni b/third_party/WebKit/Source/modules/modules_idl_files.gni
index b74fd22f..e48f4fd 100644
--- a/third_party/WebKit/Source/modules/modules_idl_files.gni
+++ b/third_party/WebKit/Source/modules/modules_idl_files.gni
@@ -245,7 +245,9 @@
                     "shapedetection/BarcodeDetector.idl",
                     "shapedetection/DetectedBarcode.idl",
                     "shapedetection/DetectedFace.idl",
+                    "shapedetection/DetectedText.idl",
                     "shapedetection/FaceDetector.idl",
+                    "shapedetection/TextDetector.idl",
                     "speech/SpeechGrammar.idl",
                     "speech/SpeechGrammarList.idl",
                     "speech/SpeechRecognition.idl",
@@ -446,6 +448,7 @@
                     "notifications/NotificationOptions.idl",
                     "payments/AndroidPayMethodData.idl",
                     "payments/AndroidPayTokenization.idl",
+                    "payments/BasicCardRequest.idl",
                     "payments/PaymentAppManifest.idl",
                     "payments/PaymentAppOption.idl",
                     "payments/PaymentAppRequestData.idl",
@@ -780,6 +783,8 @@
   "$blink_modules_output_dir/payments/AndroidPayMethodData.h",
   "$blink_modules_output_dir/payments/AndroidPayTokenization.cpp",
   "$blink_modules_output_dir/payments/AndroidPayTokenization.h",
+  "$blink_modules_output_dir/payments/BasicCardRequest.cpp",
+  "$blink_modules_output_dir/payments/BasicCardRequest.h",
   "$blink_modules_output_dir/payments/PaymentAppManifest.cpp",
   "$blink_modules_output_dir/payments/PaymentAppManifest.h",
   "$blink_modules_output_dir/payments/PaymentAppOption.cpp",
diff --git a/third_party/WebKit/Source/modules/payments/BasicCardRequest.idl b/third_party/WebKit/Source/modules/payments/BasicCardRequest.idl
new file mode 100644
index 0000000..9bd0aeb9
--- /dev/null
+++ b/third_party/WebKit/Source/modules/payments/BasicCardRequest.idl
@@ -0,0 +1,16 @@
+// 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.
+
+// https://w3c.github.io/webpayments-methods-card/#basiccardrequest
+
+enum BasicCardType {
+    "credit",
+    "debit",
+    "prepaid"
+};
+
+dictionary BasicCardRequest {
+    sequence<DOMString> supportedNetworks;
+    sequence<BasicCardType> supportedTypes;
+};
diff --git a/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp b/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp
index 15d2f3d..3c15584 100644
--- a/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp
+++ b/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp
@@ -9,6 +9,7 @@
 #include "bindings/core/v8/ScriptState.h"
 #include "bindings/core/v8/V8StringResource.h"
 #include "bindings/modules/v8/V8AndroidPayMethodData.h"
+#include "bindings/modules/v8/V8BasicCardRequest.h"
 #include "bindings/modules/v8/V8PaymentDetails.h"
 #include "core/EventTypeNames.h"
 #include "core/dom/DOMException.h"
@@ -20,6 +21,7 @@
 #include "modules/EventTargetModulesNames.h"
 #include "modules/payments/AndroidPayMethodData.h"
 #include "modules/payments/AndroidPayTokenization.h"
+#include "modules/payments/BasicCardRequest.h"
 #include "modules/payments/HTMLIFrameElementPayments.h"
 #include "modules/payments/PaymentAddress.h"
 #include "modules/payments/PaymentItem.h"
@@ -117,28 +119,10 @@
 namespace blink {
 namespace {
 
-using payments::mojom::blink::AndroidPayCardNetwork;
-using payments::mojom::blink::AndroidPayTokenization;
-
 // If the website does not call complete() 60 seconds after show() has been
 // resolved, then behave as if the website called complete("fail").
 static const int completeTimeoutSeconds = 60;
 
-const struct {
-  const AndroidPayCardNetwork code;
-  const char* name;
-} kAndroidPayNetwork[] = {{AndroidPayCardNetwork::AMEX, "AMEX"},
-                          {AndroidPayCardNetwork::DISCOVER, "DISCOVER"},
-                          {AndroidPayCardNetwork::MASTERCARD, "MASTERCARD"},
-                          {AndroidPayCardNetwork::VISA, "VISA"}};
-
-const struct {
-  const AndroidPayTokenization code;
-  const char* name;
-} kAndroidPayTokenization[] = {
-    {AndroidPayTokenization::GATEWAY_TOKEN, "GATEWAY_TOKEN"},
-    {AndroidPayTokenization::NETWORK_TOKEN, "NETWORK_TOKEN"}};
-
 // Validates ShippingOption or PaymentItem, which happen to have identical
 // fields, except for "id", which is present only in ShippingOption.
 template <typename T>
@@ -238,14 +222,14 @@
   output = payments::mojom::blink::PaymentItem::From(input);
 }
 
-void maybeSetAndroidPayMethodData(const ScriptValue& input,
-                                  PaymentMethodDataPtr& output,
-                                  ExceptionState& exceptionState) {
+// Parses Android Pay data to avoid parsing JSON in the browser.
+void setAndroidPayMethodData(const ScriptValue& input,
+                             PaymentMethodDataPtr& output,
+                             ExceptionState& exceptionState) {
   AndroidPayMethodData androidPay;
-  DummyExceptionStateForTesting dummyExceptionState;
   V8AndroidPayMethodData::toImpl(input.isolate(), input.v8Value(), androidPay,
-                                 dummyExceptionState);
-  if (dummyExceptionState.hadException())
+                                 exceptionState);
+  if (exceptionState.hadException())
     return;
 
   if (androidPay.hasEnvironment() && androidPay.environment() == "TEST")
@@ -266,10 +250,20 @@
   }
 
   if (androidPay.hasAllowedCardNetworks()) {
+    using payments::mojom::blink::AndroidPayCardNetwork;
+
+    const struct {
+      const AndroidPayCardNetwork code;
+      const char* const name;
+    } androidPayNetwork[] = {{AndroidPayCardNetwork::AMEX, "AMEX"},
+                             {AndroidPayCardNetwork::DISCOVER, "DISCOVER"},
+                             {AndroidPayCardNetwork::MASTERCARD, "MASTERCARD"},
+                             {AndroidPayCardNetwork::VISA, "VISA"}};
+
     for (const String& allowedCardNetwork : androidPay.allowedCardNetworks()) {
-      for (size_t i = 0; i < arraysize(kAndroidPayNetwork); ++i) {
-        if (allowedCardNetwork == kAndroidPayNetwork[i].name) {
-          output->allowed_card_networks.push_back(kAndroidPayNetwork[i].code);
+      for (size_t i = 0; i < arraysize(androidPayNetwork); ++i) {
+        if (allowedCardNetwork == androidPayNetwork[i].name) {
+          output->allowed_card_networks.push_back(androidPayNetwork[i].code);
           break;
         }
       }
@@ -282,10 +276,18 @@
     output->tokenization_type =
         payments::mojom::blink::AndroidPayTokenization::UNSPECIFIED;
     if (tokenization.hasTokenizationType()) {
-      for (size_t i = 0; i < arraysize(kAndroidPayTokenization); ++i) {
-        if (tokenization.tokenizationType() ==
-            kAndroidPayTokenization[i].name) {
-          output->tokenization_type = kAndroidPayTokenization[i].code;
+      using payments::mojom::blink::AndroidPayTokenization;
+
+      const struct {
+        const AndroidPayTokenization code;
+        const char* const name;
+      } androidPayTokenization[] = {
+          {AndroidPayTokenization::GATEWAY_TOKEN, "GATEWAY_TOKEN"},
+          {AndroidPayTokenization::NETWORK_TOKEN, "NETWORK_TOKEN"}};
+
+      for (size_t i = 0; i < arraysize(androidPayTokenization); ++i) {
+        if (tokenization.tokenizationType() == androidPayTokenization[i].name) {
+          output->tokenization_type = androidPayTokenization[i].code;
           break;
         }
       }
@@ -309,7 +311,63 @@
   }
 }
 
-void stringifyAndParseMethodSpecificData(const ScriptValue& input,
+// Parses basic-card data to avoid parsing JSON in the browser.
+void setBasicCardMethodData(const ScriptValue& input,
+                            PaymentMethodDataPtr& output,
+                            ExceptionState& exceptionState) {
+  BasicCardRequest basicCard;
+  V8BasicCardRequest::toImpl(input.isolate(), input.v8Value(), basicCard,
+                             exceptionState);
+  if (exceptionState.hadException())
+    return;
+
+  if (basicCard.hasSupportedNetworks()) {
+    using payments::mojom::blink::BasicCardNetwork;
+
+    const struct {
+      const BasicCardNetwork code;
+      const char* const name;
+    } basicCardNetworks[] = {{BasicCardNetwork::AMEX, "amex"},
+                             {BasicCardNetwork::DINERS, "diners"},
+                             {BasicCardNetwork::DISCOVER, "discover"},
+                             {BasicCardNetwork::JCB, "jcb"},
+                             {BasicCardNetwork::MASTERCARD, "mastercard"},
+                             {BasicCardNetwork::UNIONPAY, "unionpay"},
+                             {BasicCardNetwork::VISA, "visa"}};
+
+    for (const String& network : basicCard.supportedNetworks()) {
+      for (size_t i = 0; i < arraysize(basicCardNetworks); ++i) {
+        if (network == basicCardNetworks[i].name) {
+          output->supported_networks.append(basicCardNetworks[i].code);
+          break;
+        }
+      }
+    }
+  }
+
+  if (basicCard.hasSupportedTypes()) {
+    using payments::mojom::blink::BasicCardType;
+
+    const struct {
+      const BasicCardType code;
+      const char* const name;
+    } basicCardTypes[] = {{BasicCardType::CREDIT, "credit"},
+                          {BasicCardType::DEBIT, "debit"},
+                          {BasicCardType::PREPAID, "prepaid"}};
+
+    for (const String& type : basicCard.supportedTypes()) {
+      for (size_t i = 0; i < arraysize(basicCardTypes); ++i) {
+        if (type == basicCardTypes[i].name) {
+          output->supported_types.append(basicCardTypes[i].code);
+          break;
+        }
+      }
+    }
+  }
+}
+
+void stringifyAndParseMethodSpecificData(const Vector<String>& supportedMethods,
+                                         const ScriptValue& input,
                                          PaymentMethodDataPtr& output,
                                          ExceptionState& exceptionState) {
   DCHECK(!input.isEmpty());
@@ -328,7 +386,21 @@
 
   output->stringified_data =
       v8StringToWebCoreString<String>(value, DoNotExternalize);
-  maybeSetAndroidPayMethodData(input, output, exceptionState);
+
+  // Serialize payment method specific data to be sent to the payment apps. The
+  // payment apps are responsible for validating and processing their method
+  // data asynchronously. Do not throw exceptions here.
+  if (supportedMethods.contains("https://android.com/pay")) {
+    setAndroidPayMethodData(input, output, exceptionState);
+    if (exceptionState.hadException())
+      exceptionState.clearException();
+  }
+  if (RuntimeEnabledFeatures::paymentRequestBasicCardEnabled() &&
+      supportedMethods.contains("basic-card")) {
+    setBasicCardMethodData(input, output, exceptionState);
+    if (exceptionState.hadException())
+      exceptionState.clearException();
+  }
 }
 
 void validateAndConvertPaymentDetailsModifiers(
@@ -370,7 +442,8 @@
 
     if (modifier.hasData() && !modifier.data().isEmpty()) {
       stringifyAndParseMethodSpecificData(
-          modifier.data(), output.back()->method_data, exceptionState);
+          modifier.supportedMethods(), modifier.data(),
+          output.back()->method_data, exceptionState);
     } else {
       output.back()->method_data->stringified_data = "";
     }
@@ -458,7 +531,8 @@
     output.back()->supported_methods = paymentMethodData.supportedMethods();
 
     if (paymentMethodData.hasData() && !paymentMethodData.data().isEmpty()) {
-      stringifyAndParseMethodSpecificData(paymentMethodData.data(),
+      stringifyAndParseMethodSpecificData(paymentMethodData.supportedMethods(),
+                                          paymentMethodData.data(),
                                           output.back(), exceptionState);
     } else {
       output.back()->stringified_data = "";
@@ -621,7 +695,9 @@
     return;
 
   PaymentDetails details;
-  DummyExceptionStateForTesting exceptionState;
+  ExceptionState exceptionState(v8::Isolate::GetCurrent(),
+                                ExceptionState::ConstructionContext,
+                                "PaymentDetails");
   V8PaymentDetails::toImpl(detailsScriptValue.isolate(),
                            detailsScriptValue.v8Value(), details,
                            exceptionState);
diff --git a/third_party/WebKit/Source/modules/presentation/PresentationConnectionList.cpp b/third_party/WebKit/Source/modules/presentation/PresentationConnectionList.cpp
index a34d915..c41bfb9 100644
--- a/third_party/WebKit/Source/modules/presentation/PresentationConnectionList.cpp
+++ b/third_party/WebKit/Source/modules/presentation/PresentationConnectionList.cpp
@@ -13,7 +13,7 @@
 
 PresentationConnectionList::PresentationConnectionList(
     ExecutionContext* context)
-    : m_executionContext(context) {}
+    : ContextClient(context) {}
 
 const AtomicString& PresentationConnectionList::interfaceName() const {
   return EventTargetNames::PresentationConnectionList;
@@ -51,8 +51,8 @@
 
 DEFINE_TRACE(PresentationConnectionList) {
   visitor->trace(m_connections);
-  visitor->trace(m_executionContext);
   EventTargetWithInlineData::trace(visitor);
+  ContextClient::trace(visitor);
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/presentation/PresentationConnectionList.h b/third_party/WebKit/Source/modules/presentation/PresentationConnectionList.h
index 7d8f8d78..1abe598 100644
--- a/third_party/WebKit/Source/modules/presentation/PresentationConnectionList.h
+++ b/third_party/WebKit/Source/modules/presentation/PresentationConnectionList.h
@@ -5,11 +5,11 @@
 #ifndef PresentationConnectionList_h
 #define PresentationConnectionList_h
 
+#include "core/dom/ExecutionContext.h"
 #include "core/events/EventTarget.h"
 #include "modules/ModulesExport.h"
 #include "modules/presentation/PresentationConnection.h"
 #include "platform/heap/Handle.h"
-#include "platform/heap/Heap.h"
 
 namespace blink {
 
@@ -17,8 +17,10 @@
 // from which represents set of presentation connections in the set of
 // presentation controllers.
 class MODULES_EXPORT PresentationConnectionList final
-    : public EventTargetWithInlineData {
+    : public EventTargetWithInlineData,
+      public ContextClient {
   DEFINE_WRAPPERTYPEINFO();
+  USING_GARBAGE_COLLECTED_MIXIN(PresentationConnectionList);
 
  public:
   explicit PresentationConnectionList(ExecutionContext*);
@@ -27,7 +29,7 @@
   // EventTarget implementation.
   const AtomicString& interfaceName() const override;
   ExecutionContext* getExecutionContext() const override {
-    return m_executionContext;
+    return ContextClient::getExecutionContext();
   }
 
   // PresentationConnectionList.idl implementation.
@@ -49,7 +51,6 @@
   friend class PresentationReceiverTest;
 
   HeapVector<Member<PresentationConnection>> m_connections;
-  Member<ExecutionContext> m_executionContext;
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/shapedetection/BUILD.gn b/third_party/WebKit/Source/modules/shapedetection/BUILD.gn
index adff8921c..a4d456f 100644
--- a/third_party/WebKit/Source/modules/shapedetection/BUILD.gn
+++ b/third_party/WebKit/Source/modules/shapedetection/BUILD.gn
@@ -12,9 +12,13 @@
     "DetectedBarcode.h",
     "DetectedFace.cpp",
     "DetectedFace.h",
+    "DetectedText.cpp",
+    "DetectedText.h",
     "FaceDetector.cpp",
     "FaceDetector.h",
     "ShapeDetector.cpp",
     "ShapeDetector.h",
+    "TextDetector.cpp",
+    "TextDetector.h",
   ]
 }
diff --git a/third_party/WebKit/Source/modules/shapedetection/BarcodeDetector.cpp b/third_party/WebKit/Source/modules/shapedetection/BarcodeDetector.cpp
index 3ab69ce7..129469f 100644
--- a/third_party/WebKit/Source/modules/shapedetection/BarcodeDetector.cpp
+++ b/third_party/WebKit/Source/modules/shapedetection/BarcodeDetector.cpp
@@ -6,7 +6,6 @@
 
 #include "core/dom/DOMException.h"
 #include "core/dom/DOMRect.h"
-#include "core/frame/LocalDOMWindow.h"
 #include "core/frame/LocalFrame.h"
 #include "core/html/canvas/CanvasImageSource.h"
 #include "modules/imagecapture/Point2D.h"
diff --git a/third_party/WebKit/Source/modules/shapedetection/DetectedText.cpp b/third_party/WebKit/Source/modules/shapedetection/DetectedText.cpp
new file mode 100644
index 0000000..9551b62
--- /dev/null
+++ b/third_party/WebKit/Source/modules/shapedetection/DetectedText.cpp
@@ -0,0 +1,34 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "modules/shapedetection/DetectedText.h"
+
+#include "core/dom/DOMRect.h"
+
+namespace blink {
+
+DetectedText* DetectedText::create() {
+  return new DetectedText(emptyString(), DOMRect::create());
+}
+
+DetectedText* DetectedText::create(String rawValue, DOMRect* boundingBox) {
+  return new DetectedText(rawValue, boundingBox);
+}
+
+const String& DetectedText::rawValue() const {
+  return m_rawValue;
+}
+
+DOMRect* DetectedText::boundingBox() const {
+  return m_boundingBox.get();
+}
+
+DetectedText::DetectedText(String rawValue, DOMRect* boundingBox)
+    : m_rawValue(rawValue), m_boundingBox(boundingBox) {}
+
+DEFINE_TRACE(DetectedText) {
+  visitor->trace(m_boundingBox);
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/modules/shapedetection/DetectedText.h b/third_party/WebKit/Source/modules/shapedetection/DetectedText.h
new file mode 100644
index 0000000..6ad7316
--- /dev/null
+++ b/third_party/WebKit/Source/modules/shapedetection/DetectedText.h
@@ -0,0 +1,38 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef DetectedText_h
+#define DetectedText_h
+
+#include "bindings/core/v8/ScriptWrappable.h"
+#include "modules/ModulesExport.h"
+#include "wtf/text/WTFString.h"
+
+namespace blink {
+
+class DOMRect;
+
+class MODULES_EXPORT DetectedText final
+    : public GarbageCollectedFinalized<DetectedText>,
+      public ScriptWrappable {
+  DEFINE_WRAPPERTYPEINFO();
+
+ public:
+  static DetectedText* create();
+  static DetectedText* create(String, DOMRect*);
+
+  const String& rawValue() const;
+  DOMRect* boundingBox() const;
+  DECLARE_TRACE();
+
+ private:
+  DetectedText(String, DOMRect*);
+
+  const String m_rawValue;
+  const Member<DOMRect> m_boundingBox;
+};
+
+}  // namespace blink
+
+#endif  // DetectedText_h
diff --git a/third_party/WebKit/Source/modules/shapedetection/DetectedText.idl b/third_party/WebKit/Source/modules/shapedetection/DetectedText.idl
new file mode 100644
index 0000000..99d8306
--- /dev/null
+++ b/third_party/WebKit/Source/modules/shapedetection/DetectedText.idl
@@ -0,0 +1,13 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// https://wicg.github.io/shape-detection-api/#text-detection-api
+
+[
+    Constructor,
+    RuntimeEnabled=ShapeDetection,
+] interface DetectedText {
+    [SameObject] readonly attribute DOMRect boundingBox;
+    [SameObject] readonly attribute DOMString rawValue;
+};
diff --git a/third_party/WebKit/Source/modules/shapedetection/FaceDetector.cpp b/third_party/WebKit/Source/modules/shapedetection/FaceDetector.cpp
index ca99bb0..dd28f6ae 100644
--- a/third_party/WebKit/Source/modules/shapedetection/FaceDetector.cpp
+++ b/third_party/WebKit/Source/modules/shapedetection/FaceDetector.cpp
@@ -6,7 +6,6 @@
 
 #include "core/dom/DOMException.h"
 #include "core/dom/DOMRect.h"
-#include "core/frame/LocalDOMWindow.h"
 #include "core/frame/LocalFrame.h"
 #include "core/html/canvas/CanvasImageSource.h"
 #include "modules/shapedetection/DetectedFace.h"
diff --git a/third_party/WebKit/Source/modules/shapedetection/TextDetector.cpp b/third_party/WebKit/Source/modules/shapedetection/TextDetector.cpp
new file mode 100644
index 0000000..f204b2df
--- /dev/null
+++ b/third_party/WebKit/Source/modules/shapedetection/TextDetector.cpp
@@ -0,0 +1,77 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "modules/shapedetection/TextDetector.h"
+
+#include "core/dom/DOMException.h"
+#include "core/dom/DOMRect.h"
+#include "core/frame/LocalFrame.h"
+#include "core/html/canvas/CanvasImageSource.h"
+#include "modules/shapedetection/DetectedText.h"
+#include "public/platform/InterfaceProvider.h"
+
+namespace blink {
+
+TextDetector* TextDetector::create(Document& document) {
+  return new TextDetector(*document.frame());
+}
+
+TextDetector::TextDetector(LocalFrame& frame) : ShapeDetector(frame) {
+  frame.interfaceProvider()->getInterface(mojo::MakeRequest(&m_textService));
+  m_textService.set_connection_error_handler(convertToBaseCallback(WTF::bind(
+      &TextDetector::onTextServiceConnectionError, wrapWeakPersistent(this))));
+}
+
+ScriptPromise TextDetector::doDetect(
+    ScriptPromiseResolver* resolver,
+    mojo::ScopedSharedBufferHandle sharedBufferHandle,
+    int imageWidth,
+    int imageHeight) {
+  ScriptPromise promise = resolver->promise();
+  if (!m_textService) {
+    resolver->reject(DOMException::create(
+        NotSupportedError, "Text detection service unavailable."));
+    return promise;
+  }
+  m_textServiceRequests.add(resolver);
+  m_textService->Detect(std::move(sharedBufferHandle), imageWidth, imageHeight,
+                        convertToBaseCallback(WTF::bind(
+                            &TextDetector::onDetectText, wrapPersistent(this),
+                            wrapPersistent(resolver))));
+  return promise;
+}
+
+void TextDetector::onDetectText(
+    ScriptPromiseResolver* resolver,
+    Vector<mojom::blink::TextDetectionResultPtr> textDetectionResults) {
+  DCHECK(m_textServiceRequests.contains(resolver));
+  m_textServiceRequests.remove(resolver);
+
+  HeapVector<Member<DetectedText>> detectedText;
+  for (const auto& text : textDetectionResults) {
+    detectedText.append(DetectedText::create(
+        text->raw_value,
+        DOMRect::create(text->bounding_box->x, text->bounding_box->y,
+                        text->bounding_box->width,
+                        text->bounding_box->height)));
+  }
+
+  resolver->resolve(detectedText);
+}
+
+void TextDetector::onTextServiceConnectionError() {
+  for (const auto& request : m_textServiceRequests) {
+    request->reject(DOMException::create(NotSupportedError,
+                                         "Text Detection not implemented."));
+  }
+  m_textServiceRequests.clear();
+  m_textService.reset();
+}
+
+DEFINE_TRACE(TextDetector) {
+  ShapeDetector::trace(visitor);
+  visitor->trace(m_textServiceRequests);
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/modules/shapedetection/TextDetector.h b/third_party/WebKit/Source/modules/shapedetection/TextDetector.h
new file mode 100644
index 0000000..ac71997
--- /dev/null
+++ b/third_party/WebKit/Source/modules/shapedetection/TextDetector.h
@@ -0,0 +1,48 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef TextDetector_h
+#define TextDetector_h
+
+#include "bindings/core/v8/ScriptPromise.h"
+#include "bindings/core/v8/ScriptPromiseResolver.h"
+#include "bindings/core/v8/ScriptWrappable.h"
+#include "modules/ModulesExport.h"
+#include "modules/canvas2d/CanvasRenderingContext2D.h"
+#include "modules/shapedetection/ShapeDetector.h"
+#include "public/platform/modules/shapedetection/textdetection.mojom-blink.h"
+
+namespace blink {
+
+class LocalFrame;
+
+class MODULES_EXPORT TextDetector final : public ShapeDetector,
+                                          public ScriptWrappable {
+  DEFINE_WRAPPERTYPEINFO();
+
+ public:
+  static TextDetector* create(Document&);
+
+  DECLARE_VIRTUAL_TRACE();
+
+ private:
+  explicit TextDetector(LocalFrame&);
+  ~TextDetector() override = default;
+
+  ScriptPromise doDetect(ScriptPromiseResolver*,
+                         mojo::ScopedSharedBufferHandle,
+                         int imageWidth,
+                         int imageHeight) override;
+  void onDetectText(ScriptPromiseResolver*,
+                    Vector<mojom::blink::TextDetectionResultPtr>);
+  void onTextServiceConnectionError();
+
+  mojom::blink::TextDetectionPtr m_textService;
+
+  HeapHashSet<Member<ScriptPromiseResolver>> m_textServiceRequests;
+};
+
+}  // namespace blink
+
+#endif  // TextDetector_h
diff --git a/third_party/WebKit/Source/modules/shapedetection/TextDetector.idl b/third_party/WebKit/Source/modules/shapedetection/TextDetector.idl
new file mode 100644
index 0000000..031ab51
--- /dev/null
+++ b/third_party/WebKit/Source/modules/shapedetection/TextDetector.idl
@@ -0,0 +1,14 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// https://wicg.github.io/shape-detection-api/#text-detection-api
+
+[
+    Constructor,
+    ConstructorCallWith=Document,
+    Exposed=(Window,Worker),
+    RuntimeEnabled=ShapeDetection,
+] interface TextDetector {
+    [CallWith=ScriptState] Promise<sequence<DetectedText>> detect(ImageBitmapSource image);
+};
diff --git a/third_party/WebKit/Source/modules/vr/VRController.cpp b/third_party/WebKit/Source/modules/vr/VRController.cpp
index 58cdf5cc..0f6b8e5 100644
--- a/third_party/WebKit/Source/modules/vr/VRController.cpp
+++ b/third_party/WebKit/Source/modules/vr/VRController.cpp
@@ -23,8 +23,6 @@
       m_binding(this) {
   navigatorVR->document()->frame()->interfaceProvider()->getInterface(
       mojo::MakeRequest(&m_service));
-  m_service.set_connection_error_handler(convertToBaseCallback(
-      WTF::bind(&VRController::dispose, wrapWeakPersistent(this))));
   m_service->SetClient(
       m_binding.CreateInterfacePtrAndBind(),
       convertToBaseCallback(
@@ -34,10 +32,15 @@
 VRController::~VRController() {}
 
 void VRController::getDisplays(ScriptPromiseResolver* resolver) {
-  // If we've previously synced the VRDisplays or no longer have a valid service
-  // connection just return the current list. In the case of the service being
-  // disconnected this will be an empty array.
-  if (!m_service || m_displaySynced) {
+  if (!m_service) {
+    DOMException* exception = DOMException::create(
+        InvalidStateError, "The service is no longer active.");
+    resolver->reject(exception);
+    return;
+  }
+
+  // If we've previously synced the VRDisplays just return the current list.
+  if (m_displaySynced) {
     resolver->resolve(m_displays);
     return;
   }
@@ -103,11 +106,6 @@
   // Shutdown all displays' message pipe
   for (size_t i = 0; i < m_displays.size(); ++i)
     m_displays[i]->dispose();
-
-  m_displays.clear();
-
-  // Ensure that any outstanding getDisplays promises are resolved.
-  onGetDisplays();
 }
 
 DEFINE_TRACE(VRController) {
diff --git a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in
index 21de4eb0..1b05cdc 100644
--- a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in
+++ b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in
@@ -185,6 +185,7 @@
 PaymentDetailsModifierData status=experimental
 // PaymentRequest is enabled by default on Android
 PaymentRequest status=experimental
+PaymentRequestBasicCard status=experimental
 PaymentRequestPayerName status=stable
 PerformanceObserver status=stable
 PermissionDelegation status=test
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/git.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/git.py
index 1f8effd..47c841e 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/git.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/git.py
@@ -28,23 +28,19 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 import datetime
+import logging
 import re
 
-from webkitpy.common.checkout.scm.scm import SCM
 from webkitpy.common.memoized import memoized
 from webkitpy.common.system.executive import Executive, ScriptError
+from webkitpy.common.system.filesystem import FileSystem
+
+_log = logging.getLogger(__name__)
 
 
-class AmbiguousCommitError(Exception):
-
-    def __init__(self, num_local_commits, has_working_directory_changes):
-        Exception.__init__(self, "Found %s local commits and the working directory is %s" % (
-            num_local_commits, ["clean", "not clean"][has_working_directory_changes]))
-        self.num_local_commits = num_local_commits
-        self.has_working_directory_changes = has_working_directory_changes
-
-
-class Git(SCM):
+class Git(object):
+    # Unless otherwise specified, methods are expected to return paths relative
+    # to self.checkout_root.
 
     # Git doesn't appear to document error codes, but seems to return
     # 1 or 128, mostly.
@@ -52,15 +48,33 @@
 
     executable_name = 'git'
 
-    def __init__(self, cwd, **kwargs):
-        SCM.__init__(self, cwd, **kwargs)
+    def __init__(self, cwd, executive=None, filesystem=None):
+        self.cwd = cwd
+        self._executive = executive or Executive()
+        self._filesystem = filesystem or FileSystem()
+        self.checkout_root = self.find_checkout_root(self.cwd)
 
-    def _run_git(self, command_args, **kwargs):
+    def _run_git(self,
+                 command_args,
+                 cwd=None,
+                 input=None,  # pylint: disable=redefined-builtin
+                 timeout_seconds=None,
+                 decode_output=True,
+                 return_exit_code=False):
         full_command_args = [self.executable_name] + command_args
-        full_kwargs = kwargs
-        if 'cwd' not in full_kwargs:
-            full_kwargs['cwd'] = self.checkout_root
-        return self._run(full_command_args, **full_kwargs)
+        cwd = cwd or self.checkout_root
+        return self._executive.run_command(
+            full_command_args,
+            cwd=cwd,
+            input=input,
+            timeout_seconds=timeout_seconds,
+            return_exit_code=return_exit_code,
+            decode_output=decode_output)
+
+    # SCM always returns repository relative path, but sometimes we need
+    # absolute paths to pass to rm, etc.
+    def absolute_path(self, repository_relative_path):
+        return self._filesystem.join(self.checkout_root, repository_relative_path)
 
     @classmethod
     def in_working_directory(cls, path, executive=None):
@@ -133,21 +147,13 @@
             unstaged_changes[path] = line[1]
         return unstaged_changes
 
-    def status_command(self):
-        # git status returns non-zero when there are changes, so we use git diff name --name-status HEAD instead.
-        # No file contents printed, thus utf-8 autodecoding in self.run is fine.
-        return [self.executable_name, "diff", "--name-status", "--no-renames", "HEAD"]
-
-    def _status_regexp(self, expected_types):
-        return '^(?P<status>[%s])\t(?P<filename>.+)$' % expected_types
-
     def add_all(self, pathspec=None):
         command = ['add', '--all']
         if pathspec:
             command.append(pathspec)
         return self._run_git(command)
 
-    def add_list(self, paths, return_exit_code=False, recurse=True):
+    def add_list(self, paths, return_exit_code=False):
         return self._run_git(["add"] + paths, return_exit_code=return_exit_code)
 
     def delete_list(self, paths):
@@ -211,11 +217,28 @@
         # Added (A), Copied (C), Deleted (D), Modified (M), Renamed (R)
         return self._run_status_and_extract_filenames(status_command, self._status_regexp("ADM"))
 
-    def _added_files(self):
+    def added_files(self):
         return self._run_status_and_extract_filenames(self.status_command(), self._status_regexp("A"))
 
-    def _deleted_files(self):
-        return self._run_status_and_extract_filenames(self.status_command(), self._status_regexp("D"))
+    def _run_status_and_extract_filenames(self, status_command, status_regexp):
+        filenames = []
+        # We run with cwd=self.checkout_root so that returned-paths are root-relative.
+        for line in self._run_git(status_command, cwd=self.checkout_root).splitlines():
+            match = re.search(status_regexp, line)
+            if not match:
+                continue
+            # status = match.group('status')
+            filename = match.group('filename')
+            filenames.append(filename)
+        return filenames
+
+    def status_command(self):
+        # git status returns non-zero when there are changes, so we use git diff name --name-status HEAD instead.
+        # No file contents printed, thus utf-8 autodecoding in self.run is fine.
+        return ["diff", "--name-status", "--no-renames", "HEAD"]
+
+    def _status_regexp(self, expected_types):
+        return '^(?P<status>[%s])\t(?P<filename>.+)$' % expected_types
 
     @staticmethod
     def supports_local_commits():
@@ -236,6 +259,7 @@
         return int(match.group('commit_position'))
 
     def commit_position(self, path):
+        """Returns the latest chromium commit position found in the checkout."""
         git_log = self.most_recent_log_matching('Cr-Commit-Position:', path)
         return self._commit_position_from_git_log(git_log)
 
@@ -263,21 +287,33 @@
         Patch files are effectively binary since they may contain
         files of multiple different encodings.
         """
+        order = self._patch_order()
+        command = [
+            'diff',
+            '--binary',
+            '--no-color',
+            "--no-ext-diff",
+            "--full-index",
+            "--no-renames",
+            "--src-prefix=a/",
+            "--dst-prefix=b/",
 
+        ]
+        if order:
+            command.append(order)
+        command += [self._merge_base(git_commit), "--"]
+        if changed_files:
+            command += changed_files
+        return self._run_git(command, decode_output=False, cwd=self.checkout_root)
+
+    def _patch_order(self):
         # Put code changes at the top of the patch and layout tests
         # at the bottom, this makes for easier reviewing.
         config_path = self._filesystem.dirname(self._filesystem.path_to_module('webkitpy.common.config'))
         order_file = self._filesystem.join(config_path, 'orderfile')
-        order = ""
         if self._filesystem.exists(order_file):
-            order = "-O%s" % order_file
-
-        command = [self.executable_name, 'diff', '--binary', '--no-color', "--no-ext-diff",
-                   "--full-index", "--no-renames", "--src-prefix=a/", "--dst-prefix=b/",
-                   order, self._merge_base(git_commit), "--"]
-        if changed_files:
-            command += changed_files
-        return self._run(command, decode_output=False, cwd=self.checkout_root)
+            return "-O%s" % order_file
+        return ""
 
     @memoized
     def commit_position_from_git_commit(self, git_commit):
@@ -315,9 +351,6 @@
         command = ['commit', '--all', '-F', '-']
         self._run_git(command, input=message)
 
-    # These methods are git specific and are meant to provide support for the Git oriented workflow
-    # that Blink is moving towards, hence there are no equivalent methods in the SVN class.
-
     def pull(self, timeout_seconds=None):
         self._run_git(['pull'], timeout_seconds=timeout_seconds)
 
@@ -327,7 +360,7 @@
     def git_commits_since(self, commit):
         return self._run_git(['log', commit + '..master', '--format=%H', '--reverse']).split()
 
-    def git_commit_detail(self, commit, format=None):
+    def git_commit_detail(self, commit, format=None):  # pylint: disable=redefined-builtin
         args = ['log', '-1', commit]
         if format:
             args.append('--format=' + format)
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/scm_mock.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/git_mock.py
similarity index 60%
rename from third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/scm_mock.py
rename to third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/git_mock.py
index a6300b7f..707f3de 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/scm_mock.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/git_mock.py
@@ -1,44 +1,20 @@
-# Copyright (C) 2011 Google Inc. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-#    * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#    * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#    * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+# 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.
 
 from webkitpy.common.system.filesystem_mock import MockFileSystem
 from webkitpy.common.system.executive_mock import MockExecutive
 
 
-class MockSCM(object):
+class MockGit(object):
 
-    # Arguments are generally unused in methods that return canned values below.
-    # pylint: disable=unused-argument
+    # Arguments are listed below, even if they're unused, in order to match
+    # the Git class. pylint: disable=unused-argument
 
-    executable_name = "MockSCM"
+    executable_name = 'mock-git'
 
     def __init__(self, filesystem=None, executive=None):
-        self.checkout_root = "/mock-checkout"
+        self.checkout_root = '/mock-checkout'
         self.added_paths = set()
         self._filesystem = filesystem or MockFileSystem()
         self._executive = executive or MockExecutive()
@@ -109,8 +85,10 @@
         self._local_commits.append([message])
 
     def local_commits(self):
-        """For testing purposes, returns the internal recording of commits made via commit_locally_with_message.
-        Format as [ message, commit_all_working_directory_changes, author ].
+        """Returns the internal recording of commits made via |commit_locally_with_message|.
+
+        This is a testing convenience method; commits are formatted as:
+          [ message, commit_all_working_directory_changes, author ].
         """
         return self._local_commits
 
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/git_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/git_unittest.py
new file mode 100644
index 0000000..7305f7c
--- /dev/null
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/git_unittest.py
@@ -0,0 +1,247 @@
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import unittest
+
+from webkitpy.common.system.executive import Executive, ScriptError
+from webkitpy.common.system.executive_mock import MockExecutive
+from webkitpy.common.system.filesystem import FileSystem
+from webkitpy.common.system.filesystem_mock import MockFileSystem
+from webkitpy.common.checkout.scm.detection import detect_scm_system
+from webkitpy.common.checkout.scm.git import Git
+
+
+class GitTestWithRealFilesystemAndExecutive(unittest.TestCase):
+
+    def setUp(self):
+        self.executive = Executive()
+        self.filesystem = FileSystem()
+        self.original_cwd = self.filesystem.getcwd()
+
+        # Set up fresh git repository with one commit.
+        self.untracking_checkout_path = self._mkdtemp(suffix='-git_unittest_untracking')
+        self._run(['git', 'init', self.untracking_checkout_path])
+        self._chdir(self.untracking_checkout_path)
+        self._write_text_file('foo_file', 'foo')
+        self._run(['git', 'add', 'foo_file'])
+        self._run(['git', 'commit', '-am', 'dummy commit'])
+        self.untracking_scm = detect_scm_system(self.untracking_checkout_path)
+
+        # Then set up a second git repo that tracks the first one.
+        self.tracking_git_checkout_path = self._mkdtemp(suffix='-git_unittest_tracking')
+        self._run(['git', 'clone', '--quiet', self.untracking_checkout_path, self.tracking_git_checkout_path])
+        self._chdir(self.tracking_git_checkout_path)
+        self.tracking_scm = detect_scm_system(self.tracking_git_checkout_path)
+
+    def tearDown(self):
+        self._chdir(self.original_cwd)
+        self._run(['rm', '-rf', self.tracking_git_checkout_path])
+        self._run(['rm', '-rf', self.untracking_checkout_path])
+
+    def _join(self, *comps):
+        return self.filesystem.join(*comps)
+
+    def _chdir(self, path):
+        self.filesystem.chdir(path)
+
+    def _mkdir(self, path):
+        assert not self.filesystem.exists(path)
+        self.filesystem.maybe_make_directory(path)
+
+    def _mkdtemp(self, **kwargs):
+        return str(self.filesystem.mkdtemp(**kwargs))
+
+    def _remove(self, path):
+        self.filesystem.remove(path)
+
+    def _run(self, *args, **kwargs):
+        return self.executive.run_command(*args, **kwargs)
+
+    def _run_silent(self, args, **kwargs):
+        self.executive.run_command(args, **kwargs)
+
+    def _write_text_file(self, path, contents):
+        self.filesystem.write_text_file(path, contents)
+
+    def _write_binary_file(self, path, contents):
+        self.filesystem.write_binary_file(path, contents)
+
+    def _make_diff(self, command, *args):
+        # We use this wrapper to disable output decoding. diffs should be treated as
+        # binary files since they may include text files of multiple different encodings.
+        return self._run([command, 'diff'] + list(args), decode_output=False)
+
+    def _git_diff(self, *args):
+        return self._make_diff('git', *args)
+
+    def test_add_list(self):
+        self._chdir(self.untracking_checkout_path)
+        git = self.untracking_scm
+        self._mkdir('added_dir')
+        self._write_text_file('added_dir/added_file', 'new stuff')
+        print self._run(['ls', 'added_dir'])
+        print self._run(['pwd'])
+        print self._run(['cat', 'added_dir/added_file'])
+        git.add_list(['added_dir/added_file'])
+        self.assertIn('added_dir/added_file', git.added_files())
+
+    def test_delete_recursively(self):
+        self._chdir(self.untracking_checkout_path)
+        git = self.untracking_scm
+        self._mkdir('added_dir')
+        self._write_text_file('added_dir/added_file', 'new stuff')
+        git.add_list(['added_dir/added_file'])
+        self.assertIn('added_dir/added_file', git.added_files())
+        git.delete_list(['added_dir/added_file'])
+        self.assertNotIn('added_dir', git.added_files())
+
+    def test_delete_recursively_or_not(self):
+        self._chdir(self.untracking_checkout_path)
+        git = self.untracking_scm
+        self._mkdir('added_dir')
+        self._write_text_file('added_dir/added_file', 'new stuff')
+        self._write_text_file('added_dir/another_added_file', 'more new stuff')
+        git.add_list(['added_dir/added_file', 'added_dir/another_added_file'])
+        self.assertIn('added_dir/added_file', git.added_files())
+        self.assertIn('added_dir/another_added_file', git.added_files())
+        git.delete_list(['added_dir/added_file'])
+        self.assertIn('added_dir/another_added_file', git.added_files())
+
+    def test_exists(self):
+        self._chdir(self.untracking_checkout_path)
+        git = self.untracking_scm
+        self._chdir(git.checkout_root)
+        self.assertFalse(git.exists('foo.txt'))
+        self._write_text_file('foo.txt', 'some stuff')
+        self.assertFalse(git.exists('foo.txt'))
+        git.add_list(['foo.txt'])
+        git.commit_locally_with_message('adding foo')
+        self.assertTrue(git.exists('foo.txt'))
+        git.delete_list(['foo.txt'])
+        git.commit_locally_with_message('deleting foo')
+        self.assertFalse(git.exists('foo.txt'))
+
+    def test_move(self):
+        self._chdir(self.untracking_checkout_path)
+        git = self.untracking_scm
+        self._write_text_file('added_file', 'new stuff')
+        git.add_list(['added_file'])
+        git.move('added_file', 'moved_file')
+        self.assertIn('moved_file', git.added_files())
+
+    def test_move_recursive(self):
+        self._chdir(self.untracking_checkout_path)
+        git = self.untracking_scm
+        self._mkdir('added_dir')
+        self._write_text_file('added_dir/added_file', 'new stuff')
+        self._write_text_file('added_dir/another_added_file', 'more new stuff')
+        git.add_list(['added_dir'])
+        git.move('added_dir', 'moved_dir')
+        self.assertIn('moved_dir/added_file', git.added_files())
+        self.assertIn('moved_dir/another_added_file', git.added_files())
+
+    def test_remote_branch_ref(self):
+        # This tests a protected method. pylint: disable=protected-access
+        self.assertEqual(self.tracking_scm._remote_branch_ref(), 'refs/remotes/origin/master')
+        self._chdir(self.untracking_checkout_path)
+        self.assertRaises(ScriptError, self.untracking_scm._remote_branch_ref)
+
+    def test_create_patch(self):
+        self._chdir(self.tracking_git_checkout_path)
+        git = self.tracking_scm
+        self._write_text_file('test_file_commit1', 'contents')
+        self._run(['git', 'add', 'test_file_commit1'])
+        git.commit_locally_with_message('message')
+        git._patch_order = lambda: ''  # pylint: disable=protected-access
+        patch = git.create_patch()
+        self.assertNotRegexpMatches(patch, r'Subversion Revision:')
+
+    def test_patches_have_filenames_with_prefixes(self):
+        self._chdir(self.tracking_git_checkout_path)
+        git = self.tracking_scm
+        self._write_text_file('test_file_commit1', 'contents')
+        self._run(['git', 'add', 'test_file_commit1'])
+        git.commit_locally_with_message('message')
+
+        # Even if diff.noprefix is enabled, create_patch() produces diffs with prefixes.
+        self._run(['git', 'config', 'diff.noprefix', 'true'])
+        git._patch_order = lambda: ''  # pylint: disable=protected-access
+        patch = git.create_patch()
+        self.assertRegexpMatches(patch, r'^diff --git a/test_file_commit1 b/test_file_commit1')
+
+    def test_rename_files(self):
+        self._chdir(self.tracking_git_checkout_path)
+        git = self.tracking_scm
+        git.move('foo_file', 'bar_file')
+        git.commit_locally_with_message('message')
+
+    def test_commit_position_from_git_log(self):
+        # This tests a protected method. pylint: disable=protected-access
+        git_log = """
+commit 624c3081c0
+Author: foobarbaz1 <foobarbaz1@chromium.org>
+Date:   Mon Sep 28 19:10:30 2015 -0700
+
+    Test foo bar baz qux 123.
+
+    BUG=000000
+
+    Review URL: https://codereview.chromium.org/999999999
+
+    Cr-Commit-Position: refs/heads/master@{#1234567}
+"""
+        self._chdir(self.tracking_git_checkout_path)
+        git = self.tracking_scm
+        self.assertEqual(git._commit_position_from_git_log(git_log), 1234567)
+
+    def test_timestamp_of_revision(self):
+        # This tests a protected method. pylint: disable=protected-access
+        self._chdir(self.tracking_git_checkout_path)
+        git = self.tracking_scm
+        position_regex = git._commit_position_regex_for_timestamp()
+        git.most_recent_log_matching(position_regex, git.checkout_root)
+
+
+class GitTestWithMock(unittest.TestCase):
+
+    def make_scm(self):
+        git = Git(cwd='.', executive=MockExecutive(), filesystem=MockFileSystem())
+        git.read_git_config = lambda *args, **kw: 'MOCKKEY:MOCKVALUE'
+        return git
+
+    def _assert_timestamp_of_revision(self, canned_git_output, expected):
+        git = self.make_scm()
+        git.find_checkout_root = lambda path: ''
+        # Modifying protected method. pylint: disable=protected-access
+        git._run_git = lambda args: canned_git_output
+        self.assertEqual(git.timestamp_of_revision('some-path', '12345'), expected)
+
+    def test_timestamp_of_revision_utc(self):
+        self._assert_timestamp_of_revision('Date: 2013-02-08 08:05:49 +0000', '2013-02-08T08:05:49Z')
+
+    def test_timestamp_of_revision_positive_timezone(self):
+        self._assert_timestamp_of_revision('Date: 2013-02-08 01:02:03 +0130', '2013-02-07T23:32:03Z')
+
+    def test_timestamp_of_revision_pacific_timezone(self):
+        self._assert_timestamp_of_revision('Date: 2013-02-08 01:55:21 -0800', '2013-02-08T09:55:21Z')
+
+    def test_unstaged_files(self):
+        scm = self.make_scm()
+        status_lines = [
+            ' M d/modified.txt',
+            ' D d/deleted.txt',
+            '?? d/untracked.txt',
+            'D  d/deleted.txt',
+            'M  d/modified-staged.txt',
+            'A  d/added-staged.txt',
+        ]
+        # pylint: disable=protected-access
+        scm._run_git = lambda args: '\x00'.join(status_lines) + '\x00'
+        self.assertEqual(
+            scm.unstaged_changes(),
+            {
+                'd/modified.txt': 'M',
+                'd/deleted.txt': 'D',
+                'd/untracked.txt': '?',
+            })
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/scm.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/scm.py
deleted file mode 100644
index b5bb031..0000000
--- a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/scm.py
+++ /dev/null
@@ -1,161 +0,0 @@
-# Copyright (c) 2009, Google Inc. All rights reserved.
-# Copyright (c) 2009 Apple Inc. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-#     * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#     * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-# Python module for interacting with an SCM system (like SVN or Git)
-
-import logging
-import re
-import sys
-
-from webkitpy.common.system.executive import Executive
-from webkitpy.common.system.filesystem import FileSystem
-
-_log = logging.getLogger(__name__)
-
-
-# SCM methods are expected to return paths relative to self.checkout_root.
-class SCM:
-
-    # Arguments are generally unused in abstract base methods below.
-    # pylint: disable=unused-argument
-
-    def __init__(self, cwd, executive=None, filesystem=None):
-        self.cwd = cwd
-        self._executive = executive or Executive()
-        self._filesystem = filesystem or FileSystem()
-        self.checkout_root = self.find_checkout_root(self.cwd)
-
-    # A wrapper used by subclasses to create processes.
-    def _run(self,
-             args,
-             cwd=None,
-             # pylint: disable=redefined-builtin
-             input=None,
-             timeout_seconds=None,
-             error_handler=None,
-             return_exit_code=False,
-             return_stderr=True,
-             decode_output=True):
-        # FIXME: We should set cwd appropriately.
-        return self._executive.run_command(args,
-                                           cwd=cwd,
-                                           input=input,
-                                           timeout_seconds=timeout_seconds,
-                                           error_handler=error_handler,
-                                           return_exit_code=return_exit_code,
-                                           return_stderr=return_stderr,
-                                           decode_output=decode_output)
-
-    # SCM always returns repository relative path, but sometimes we need
-    # absolute paths to pass to rm, etc.
-    def absolute_path(self, repository_relative_path):
-        return self._filesystem.join(self.checkout_root, repository_relative_path)
-
-    def _run_status_and_extract_filenames(self, status_command, status_regexp):
-        filenames = []
-        # We run with cwd=self.checkout_root so that returned-paths are root-relative.
-        for line in self._run(status_command, cwd=self.checkout_root).splitlines():
-            match = re.search(status_regexp, line)
-            if not match:
-                continue
-            # status = match.group('status')
-            filename = match.group('filename')
-            filenames.append(filename)
-        return filenames
-
-    @staticmethod
-    def _subclass_must_implement():
-        raise NotImplementedError("subclasses must implement")
-
-    @classmethod
-    def in_working_directory(cls, path, executive=None):
-        SCM._subclass_must_implement()
-
-    def find_checkout_root(self, path):
-        SCM._subclass_must_implement()
-
-    def add_all(self, pathspec=None):
-        self._subclass_must_implement()
-
-    def add(self, path, return_exit_code=False, recurse=True):
-        self.add_list([path], return_exit_code, recurse)
-
-    def add_list(self, paths, return_exit_code=False, recurse=True):
-        self._subclass_must_implement()
-
-    def delete(self, path):
-        self.delete_list([path])
-
-    def delete_list(self, paths):
-        self._subclass_must_implement()
-
-    def move(self, origin, destination):
-        self._subclass_must_implement()
-
-    def exists(self, path):
-        self._subclass_must_implement()
-
-    def unstaged_changes(self):
-        self._subclass_must_implement()
-
-    def changed_files(self, git_commit=None):
-        self._subclass_must_implement()
-
-    def _added_files(self):
-        self._subclass_must_implement()
-
-    def _deleted_files(self):
-        self._subclass_must_implement()
-
-    def display_name(self):
-        self._subclass_must_implement()
-
-    def commit_position(self, path):
-        """Returns the latest chromium commit position found in the checkout."""
-        self._subclass_must_implement()
-
-    def timestamp_of_revision(self, path, revision):
-        self._subclass_must_implement()
-
-    def blame(self, path):
-        self._subclass_must_implement()
-
-    def has_working_directory_changes(self, pathspec=None):
-        self._subclass_must_implement()
-
-    #--------------------------------------------------------------------------
-    # Subclasses must indicate if they support local commits,
-    # but the SCM baseclass will only call local_commits methods when this is true.
-    @staticmethod
-    def supports_local_commits():
-        SCM._subclass_must_implement()
-
-    def commit_locally_with_message(self, message):
-        _log.error("Your source control manager does not support local commits.")
-        sys.exit(1)
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/scm_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/scm_unittest.py
deleted file mode 100644
index c3507e01..0000000
--- a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/scm_unittest.py
+++ /dev/null
@@ -1,278 +0,0 @@
-# Copyright (C) 2009 Google Inc. All rights reserved.
-# Copyright (C) 2009 Apple Inc. All rights reserved.
-# Copyright (C) 2011 Daniel Bates (dbates@intudata.com). All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-#    * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#    * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#    * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-import unittest
-
-from webkitpy.common.system.executive import Executive, ScriptError
-from webkitpy.common.system.executive_mock import MockExecutive
-from webkitpy.common.system.filesystem import FileSystem
-from webkitpy.common.system.filesystem_mock import MockFileSystem
-from webkitpy.common.checkout.scm.detection import detect_scm_system
-from webkitpy.common.checkout.scm.git import Git
-
-
-class SCMTestBase(unittest.TestCase):
-
-    def __init__(self, *args, **kwargs):
-        super(SCMTestBase, self).__init__(*args, **kwargs)
-        self.scm = None
-        self.executive = None
-        self.fs = None
-        self.original_cwd = None
-
-    def setUp(self):
-        self.executive = Executive()
-        self.fs = FileSystem()
-        self.original_cwd = self.fs.getcwd()
-
-    def tearDown(self):
-        self._chdir(self.original_cwd)
-
-    def _join(self, *comps):
-        return self.fs.join(*comps)
-
-    def _chdir(self, path):
-        self.fs.chdir(path)
-
-    def _mkdir(self, path):
-        assert not self.fs.exists(path)
-        self.fs.maybe_make_directory(path)
-
-    def _mkdtemp(self, **kwargs):
-        return str(self.fs.mkdtemp(**kwargs))
-
-    def _remove(self, path):
-        self.fs.remove(path)
-
-    def _rmtree(self, path):
-        self.fs.rmtree(path)
-
-    def _run(self, *args, **kwargs):
-        return self.executive.run_command(*args, **kwargs)
-
-    def _run_silent(self, args, **kwargs):
-        self.executive.run_command(args, **kwargs)
-
-    def _write_text_file(self, path, contents):
-        self.fs.write_text_file(path, contents)
-
-    def _write_binary_file(self, path, contents):
-        self.fs.write_binary_file(path, contents)
-
-    def _make_diff(self, command, *args):
-        # We use this wrapper to disable output decoding. diffs should be treated as
-        # binary files since they may include text files of multiple different encodings.
-        return self._run([command, "diff"] + list(args), decode_output=False)
-
-    def _git_diff(self, *args):
-        return self._make_diff("git", *args)
-
-    def _shared_test_add_recursively(self):
-        self._mkdir("added_dir")
-        self._write_text_file("added_dir/added_file", "new stuff")
-        self.scm.add("added_dir/added_file")
-        self.assertIn("added_dir/added_file", self.scm._added_files())
-
-    def _shared_test_delete_recursively(self):
-        self._mkdir("added_dir")
-        self._write_text_file("added_dir/added_file", "new stuff")
-        self.scm.add("added_dir/added_file")
-        self.assertIn("added_dir/added_file", self.scm._added_files())
-        self.scm.delete("added_dir/added_file")
-        self.assertNotIn("added_dir", self.scm._added_files())
-
-    def _shared_test_delete_recursively_or_not(self):
-        self._mkdir("added_dir")
-        self._write_text_file("added_dir/added_file", "new stuff")
-        self._write_text_file("added_dir/another_added_file", "more new stuff")
-        self.scm.add("added_dir/added_file")
-        self.scm.add("added_dir/another_added_file")
-        self.assertIn("added_dir/added_file", self.scm._added_files())
-        self.assertIn("added_dir/another_added_file", self.scm._added_files())
-        self.scm.delete("added_dir/added_file")
-        self.assertIn("added_dir/another_added_file", self.scm._added_files())
-
-    def _shared_test_exists(self, scm, commit_function):
-        self._chdir(scm.checkout_root)
-        self.assertFalse(scm.exists('foo.txt'))
-        self._write_text_file('foo.txt', 'some stuff')
-        self.assertFalse(scm.exists('foo.txt'))
-        scm.add('foo.txt')
-        commit_function('adding foo')
-        self.assertTrue(scm.exists('foo.txt'))
-        scm.delete('foo.txt')
-        commit_function('deleting foo')
-        self.assertFalse(scm.exists('foo.txt'))
-
-    def _shared_test_move(self):
-        self._write_text_file('added_file', 'new stuff')
-        self.scm.add('added_file')
-        self.scm.move('added_file', 'moved_file')
-        self.assertIn('moved_file', self.scm._added_files())
-
-    def _shared_test_move_recursive(self):
-        self._mkdir("added_dir")
-        self._write_text_file('added_dir/added_file', 'new stuff')
-        self._write_text_file('added_dir/another_added_file', 'more new stuff')
-        self.scm.add('added_dir')
-        self.scm.move('added_dir', 'moved_dir')
-        self.assertIn('moved_dir/added_file', self.scm._added_files())
-        self.assertIn('moved_dir/another_added_file', self.scm._added_files())
-
-
-class GitTest(SCMTestBase):
-
-    def setUp(self):
-        super(GitTest, self).setUp()
-        self._set_up_git_checkouts()
-
-    def tearDown(self):
-        super(GitTest, self).tearDown()
-        self._tear_down_git_checkouts()
-
-    def _set_up_git_checkouts(self):
-        """Sets up fresh git repository with one commit. Then sets up a second git repo that tracks the first one."""
-
-        self.untracking_checkout_path = self._mkdtemp(suffix="git_test_checkout2")
-        self._run(['git', 'init', self.untracking_checkout_path])
-
-        self._chdir(self.untracking_checkout_path)
-        self._write_text_file('foo_file', 'foo')
-        self._run(['git', 'add', 'foo_file'])
-        self._run(['git', 'commit', '-am', 'dummy commit'])
-        self.untracking_scm = detect_scm_system(self.untracking_checkout_path)
-
-        self.tracking_git_checkout_path = self._mkdtemp(suffix="git_test_checkout")
-        self._run(['git', 'clone', '--quiet', self.untracking_checkout_path, self.tracking_git_checkout_path])
-        self._chdir(self.tracking_git_checkout_path)
-        self.tracking_scm = detect_scm_system(self.tracking_git_checkout_path)
-
-    def _tear_down_git_checkouts(self):
-        self._run(['rm', '-rf', self.tracking_git_checkout_path])
-        self._run(['rm', '-rf', self.untracking_checkout_path])
-
-    def test_remote_branch_ref(self):
-        self.assertEqual(self.tracking_scm._remote_branch_ref(), 'refs/remotes/origin/master')
-        self._chdir(self.untracking_checkout_path)
-        self.assertRaises(ScriptError, self.untracking_scm._remote_branch_ref)
-
-    def test_create_patch(self):
-        self._write_text_file('test_file_commit1', 'contents')
-        self._run(['git', 'add', 'test_file_commit1'])
-        scm = self.tracking_scm
-        scm.commit_locally_with_message('message')
-
-        patch = scm.create_patch()
-        self.assertNotRegexpMatches(patch, r'Subversion Revision:')
-
-    def test_patches_have_filenames_with_prefixes(self):
-        self._write_text_file('test_file_commit1', 'contents')
-        self._run(['git', 'add', 'test_file_commit1'])
-        scm = self.tracking_scm
-        scm.commit_locally_with_message('message')
-
-        # Even if diff.noprefix is enabled, create_patch() produces diffs with prefixes.
-        self._run(['git', 'config', 'diff.noprefix', 'true'])
-        patch = scm.create_patch()
-        self.assertRegexpMatches(patch, r'^diff --git a/test_file_commit1 b/test_file_commit1')
-
-    def test_exists(self):
-        scm = self.untracking_scm
-        self._shared_test_exists(scm, scm.commit_locally_with_message)
-
-    def test_rename_files(self):
-        scm = self.tracking_scm
-        scm.move('foo_file', 'bar_file')
-        scm.commit_locally_with_message('message')
-
-    def test_commit_position_from_git_log(self):
-        git_log = """
-commit 624c3081c0
-Author: foobarbaz1 <foobarbaz1@chromium.org>
-Date:   Mon Sep 28 19:10:30 2015 -0700
-
-    Test foo bar baz qux 123.
-
-    BUG=000000
-
-    Review URL: https://codereview.chromium.org/999999999
-
-    Cr-Commit-Position: refs/heads/master@{#1234567}
-"""
-        scm = self.tracking_scm
-        self.assertEqual(scm._commit_position_from_git_log(git_log), 1234567)
-
-    def test_timestamp_of_revision(self):
-        scm = self.tracking_scm
-        scm.most_recent_log_matching(scm._commit_position_regex_for_timestamp(), scm.checkout_root)
-
-
-class GitTestWithMock(SCMTestBase):
-
-    def make_scm(self):
-        scm = Git(cwd=".", executive=MockExecutive(), filesystem=MockFileSystem())
-        scm.read_git_config = lambda *args, **kw: "MOCKKEY:MOCKVALUE"
-        return scm
-
-    def test_timestamp_of_revision(self):
-        scm = self.make_scm()
-        scm.find_checkout_root = lambda path: ''
-        scm._run_git = lambda args: 'Date: 2013-02-08 08:05:49 +0000'
-        self.assertEqual(scm.timestamp_of_revision('some-path', '12345'), '2013-02-08T08:05:49Z')
-
-        scm._run_git = lambda args: 'Date: 2013-02-08 01:02:03 +0130'
-        self.assertEqual(scm.timestamp_of_revision('some-path', '12345'), '2013-02-07T23:32:03Z')
-
-        scm._run_git = lambda args: 'Date: 2013-02-08 01:55:21 -0800'
-        self.assertEqual(scm.timestamp_of_revision('some-path', '12345'), '2013-02-08T09:55:21Z')
-
-    def test_unstaged_files(self):
-        scm = self.make_scm()
-        lines = [
-            ' M d/modified.txt',
-            ' D d/deleted.txt',
-            '?? d/untracked.txt',
-            'D  d/deleted.txt',
-            'M  d/modified-staged.txt',
-            'A  d/added-staged.txt',
-        ]
-        scm._run_git = lambda _: '\x00'.join(lines) + '\x00'  # pylint: disable=protected-access
-        self.assertEqual(
-            scm.unstaged_changes(),
-            {
-                'd/modified.txt': 'M',
-                'd/deleted.txt': 'D',
-                'd/untracked.txt': '?',
-            })
-
-    def test_unstaged_files_with_no_changes(self):
-        scm = self.make_scm()
-        scm._run_git = lambda _: '\x00'  # pylint: disable=protected-access
-        self.assertEqual(scm.unstaged_changes(), {})
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/host_mock.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/host_mock.py
index 9a62e2a..d00ba69d 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/common/host_mock.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/host_mock.py
@@ -27,7 +27,7 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 from webkitpy.common.config.builders import BUILDERS
-from webkitpy.common.checkout.scm.scm_mock import MockSCM
+from webkitpy.common.checkout.scm.git_mock import MockGit
 from webkitpy.common.net.buildbot_mock import MockBuildBot
 from webkitpy.common.net.web_mock import MockWeb
 from webkitpy.common.system.system_host_mock import MockSystemHost
@@ -72,7 +72,7 @@
 
     def initialize_scm(self, patch_directories=None):
         if not self._scm:
-            self._scm = MockSCM(filesystem=self.filesystem, executive=self.executive)
+            self._scm = MockGit(filesystem=self.filesystem, executive=self.executive)
         # Various pieces of code (wrongly) call filesystem.chdir(checkout_root).
         # Making the checkout_root exist in the mock filesystem makes that chdir not raise.
         self.filesystem.maybe_make_directory(self._scm.checkout_root)
diff --git a/third_party/WebKit/public/BUILD.gn b/third_party/WebKit/public/BUILD.gn
index cc54981..dcd551b 100644
--- a/third_party/WebKit/public/BUILD.gn
+++ b/third_party/WebKit/public/BUILD.gn
@@ -664,6 +664,7 @@
     "platform/modules/shapedetection/barcodedetection.mojom",
     "platform/modules/shapedetection/facedetection.mojom",
     "platform/modules/shapedetection/facedetection_provider.mojom",
+    "platform/modules/shapedetection/textdetection.mojom",
     "platform/modules/websockets/websocket.mojom",
     "platform/referrer.mojom",
     "platform/site_engagement.mojom",
diff --git a/third_party/WebKit/public/platform/modules/shapedetection/textdetection.mojom b/third_party/WebKit/public/platform/modules/shapedetection/textdetection.mojom
new file mode 100644
index 0000000..e7c01b6
--- /dev/null
+++ b/third_party/WebKit/public/platform/modules/shapedetection/textdetection.mojom
@@ -0,0 +1,19 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+module blink.mojom;
+
+import "ui/gfx/geometry/mojo/geometry.mojom";
+
+struct TextDetectionResult {
+  string raw_value;
+  gfx.mojom.RectF bounding_box;
+};
+
+interface TextDetection {
+  // |frame_data| contains tightly packed image pixels in ARGB32 format,
+  // row-major order.
+  Detect(handle<shared_buffer> frame_data, uint32 width, uint32 height)
+    => (array<TextDetectionResult> results);
+};
diff --git a/third_party/dom_distiller_js/README.chromium b/third_party/dom_distiller_js/README.chromium
index 43a439d..7ef25ff 100644
--- a/third_party/dom_distiller_js/README.chromium
+++ b/third_party/dom_distiller_js/README.chromium
@@ -1,6 +1,6 @@
 Name: dom-distiller-js
 URL: https://github.com/chromium/dom-distiller
-Version: 072fe57b48
+Version: aab1a1b038
 License: BSD
 Security Critical: yes
 
diff --git a/tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp b/tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp
index e2b797f..945c6865 100644
--- a/tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp
+++ b/tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp
@@ -367,6 +367,41 @@
   return output;
 }
 
+bool CanBeEvaluatedAtCompileTime(const clang::Stmt* stmt,
+                                 const clang::ASTContext& context) {
+  auto* expr = clang::dyn_cast<clang::Expr>(stmt);
+  if (!expr) {
+    // If the statement is not an expression then it's a constant.
+    return true;
+  }
+
+  // Function calls create non-consistent behaviour. For some template
+  // instantiations they can be constexpr while for others they are not, which
+  // changes the output of isEvaluatable().
+  if (expr->hasNonTrivialCall(context))
+    return false;
+
+  // Recurse on children. If they are all const (or are uses of template
+  // input) then the statement can be considered const. For whatever reason the
+  // below checks can give different-and-less-consistent responses if we call
+  // them on a complex expression than if we call them on the most primitive
+  // pieces (some pieces would say false but the whole thing says true).
+  for (auto* child : expr->children()) {
+    if (!CanBeEvaluatedAtCompileTime(child, context))
+      return false;
+  }
+
+  // If the expression is a template input then its coming at compile time so
+  // we consider it const. And we can't check isEvaluatable() in this case as
+  // it will do bad things/crash.
+  if (expr->isInstantiationDependent())
+    return true;
+
+  // If the expression can be evaluated at compile time, then it should have a
+  // kFoo style name. Otherwise, not.
+  return expr->isEvaluatable(context);
+}
+
 bool IsProbablyConst(const clang::VarDecl& decl,
                      const clang::ASTContext& context) {
   clang::QualType type = decl.getType();
@@ -390,18 +425,7 @@
   if (!initializer)
     return false;
 
-  // If the expression is dependent on a template input, then we are not
-  // sure if it can be compile-time generated as calling isEvaluatable() is
-  // not valid on |initializer|.
-  // TODO(crbug.com/581218): We could probably look at each compiled
-  // instantiation of the template and see if they are all compile-time
-  // isEvaluable().
-  if (initializer->isInstantiationDependent())
-    return false;
-
-  // If the expression can be evaluated at compile time, then it should have a
-  // kFoo style name. Otherwise, not.
-  return initializer->isEvaluatable(context);
+  return CanBeEvaluatedAtCompileTime(initializer, context);
 }
 
 AST_MATCHER_P(clang::QualType, hasString, std::string, ExpectedString) {
@@ -627,6 +651,12 @@
     if (original_name.size() >= 2 && original_name[0] == 'k' &&
         clang::isUppercase(original_name[1]))
       return false;
+    // Or names are spelt with underscore casing. While they are actually
+    // compile consts, the author wrote it explicitly as a variable not as
+    // a constant (they would have used kFormat otherwise here), so preserve
+    // it rather than try to mangle a kFormat out of it.
+    if (original_name.find('_') != StringRef::npos)
+      return false;
 
     name = 'k';
     name.append(original_name.data(), original_name.size());
diff --git a/tools/clang/rewrite_to_chrome_style/tests/constants-expected.cc b/tools/clang/rewrite_to_chrome_style/tests/constants-expected.cc
index 3f55421..4b2f89f 100644
--- a/tools/clang/rewrite_to_chrome_style/tests/constants-expected.cc
+++ b/tools/clang/rewrite_to_chrome_style/tests/constants-expected.cc
@@ -33,10 +33,10 @@
     const int kFunctionConstantFromExpression = 4 + 6;
     const int kFunctionConstantFromOtherConsts =
         kFunctionConstant + kFunctionConstantFromExpression;
-    // These don't do the right thing right now, but names like this don't
-    // exist in blink (hopefully).
-    const int kShould_be_renamed_to_a_const = 9 - 2;
-    const int kShould_also_be_renamed_to_a_const =
+    // These are constants but they are hacker_case, so we just leave them as
+    // is since the author explicitly did this.
+    const int should_not_be_renamed_to_a_const = 9 - 2;
+    const int should_not_also_be_renamed_to_a_const =
         kFunctionConstant + kFunctionConstantFromOtherConsts;
     const int not_compile_time_const = kFunctionConstant + Function();
   }
diff --git a/tools/clang/rewrite_to_chrome_style/tests/constants-original.cc b/tools/clang/rewrite_to_chrome_style/tests/constants-original.cc
index 51ce017..8e06731 100644
--- a/tools/clang/rewrite_to_chrome_style/tests/constants-original.cc
+++ b/tools/clang/rewrite_to_chrome_style/tests/constants-original.cc
@@ -33,10 +33,10 @@
     const int kFunctionConstantFromExpression = 4 + 6;
     const int kFunctionConstantFromOtherConsts =
         kFunctionConstant + kFunctionConstantFromExpression;
-    // These don't do the right thing right now, but names like this don't
-    // exist in blink (hopefully).
-    const int should_be_renamed_to_a_const = 9 - 2;
-    const int should_also_be_renamed_to_a_const =
+    // These are constants but they are hacker_case, so we just leave them as
+    // is since the author explicitly did this.
+    const int should_not_be_renamed_to_a_const = 9 - 2;
+    const int should_not_also_be_renamed_to_a_const =
         kFunctionConstant + kFunctionConstantFromOtherConsts;
     const int not_compile_time_const = kFunctionConstant + Function();
   }
diff --git a/tools/clang/rewrite_to_chrome_style/tests/template-expected.cc b/tools/clang/rewrite_to_chrome_style/tests/template-expected.cc
index c62e8d0e..dc46c19a3a 100644
--- a/tools/clang/rewrite_to_chrome_style/tests/template-expected.cc
+++ b/tools/clang/rewrite_to_chrome_style/tests/template-expected.cc
@@ -36,20 +36,44 @@
 
 namespace blink {
 
+bool FunctionNotMarkedConstexpr(int a) {
+  return a == 4 || a == 10;
+}
+
+template <typename T>
+bool TemplatedFunctionNotMarkedConstexpr(T t) {
+  return !!t;
+}
+
+int g_global_number;
+
 template <typename T, int number>
 void F() {
-  // We don't assert on this, and we don't end up considering it a const for
-  // now.
+  // These are const but hacker_case so we leave them alone.
   const int maybe_a_const = sizeof(T);
   const int is_a_const = number;
+  // These are const expressions so they get a k prefix.
+  const int kMaybeAConstToo = sizeof(T);
+  const int kIsAConstToo = number;
+  // These are built from calls to functions which produces inconsistent
+  // results so they should not be considered const to be safe.
+  const bool from_a_method = FunctionNotMarkedConstexpr(number);
+  const bool from_a_templated_method =
+      TemplatedFunctionNotMarkedConstexpr(number);
+  // A complex statement of const things is const.
+  const bool kComplexConst = number || (number + 1);
+  // A complex statement with a non-const thing is not const.
+  const bool complex_not_const = number || (g_global_number + 1);
 }
 
 template <int number, typename... T>
 void F() {
-  // We don't assert on this, and we don't end up considering it a const for
-  // now.
+  // These are const but hacker_case so we leave them alone.
   const int maybe_a_const = sizeof...(T);
   const int is_a_const = number;
+  // These are const expressions so they get a k prefix.
+  const int kMaybeAConstToo = sizeof...(T);
+  const int kIsAConstToo = number;
 }
 
 namespace test_template_arg_is_function {
@@ -66,6 +90,15 @@
   H<int, F>(0);
   // Non-Blink should stay the same.
   H<int, not_blink::function>(1);
+
+  // The int one makes the methods called from F() considered as constexpr, and
+  // can be collapsed to not have template arguments before it reaches the AST.
+  F<int, 10>();
+  // The enum one makes them not constexpr, as it doesn't collapse away the
+  // template stuff as much. This can lead to conflicting decisions about
+  // the names inside F() vs the above instantiation.
+  enum E { A };
+  F<E, 11>();
 }
 
 }  // namespace test_template_arg_is_function
diff --git a/tools/clang/rewrite_to_chrome_style/tests/template-original.cc b/tools/clang/rewrite_to_chrome_style/tests/template-original.cc
index 199f4a0..754e755 100644
--- a/tools/clang/rewrite_to_chrome_style/tests/template-original.cc
+++ b/tools/clang/rewrite_to_chrome_style/tests/template-original.cc
@@ -36,20 +36,43 @@
 
 namespace blink {
 
+bool functionNotMarkedConstexpr(int a) {
+  return a == 4 || a == 10;
+}
+
+template <typename T>
+bool templatedFunctionNotMarkedConstexpr(T t) {
+  return !!t;
+}
+
+int g_globalNumber;
+
 template <typename T, int number>
 void F() {
-  // We don't assert on this, and we don't end up considering it a const for
-  // now.
+  // These are const but hacker_case so we leave them alone.
   const int maybe_a_const = sizeof(T);
   const int is_a_const = number;
+  // These are const expressions so they get a k prefix.
+  const int maybeAConstToo = sizeof(T);
+  const int isAConstToo = number;
+  // These are built from calls to functions which produces inconsistent
+  // results so they should not be considered const to be safe.
+  const bool fromAMethod = functionNotMarkedConstexpr(number);
+  const bool fromATemplatedMethod = templatedFunctionNotMarkedConstexpr(number);
+  // A complex statement of const things is const.
+  const bool complexConst = number || (number + 1);
+  // A complex statement with a non-const thing is not const.
+  const bool complexNotConst = number || (g_globalNumber + 1);
 }
 
 template <int number, typename... T>
 void F() {
-  // We don't assert on this, and we don't end up considering it a const for
-  // now.
+  // These are const but hacker_case so we leave them alone.
   const int maybe_a_const = sizeof...(T);
   const int is_a_const = number;
+  // These are const expressions so they get a k prefix.
+  const int maybeAConstToo = sizeof...(T);
+  const int isAConstToo = number;
 }
 
 namespace test_template_arg_is_function {
@@ -66,6 +89,15 @@
   h<int, f>(0);
   // Non-Blink should stay the same.
   h<int, not_blink::function>(1);
+
+  // The int one makes the methods called from F() considered as constexpr, and
+  // can be collapsed to not have template arguments before it reaches the AST.
+  F<int, 10>();
+  // The enum one makes them not constexpr, as it doesn't collapse away the
+  // template stuff as much. This can lead to conflicting decisions about
+  // the names inside F() vs the above instantiation.
+  enum E { A };
+  F<E, 11>();
 }
 
 }  // namespace test_template_arg_is_function
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml
index a21822cb..1c2afd9 100644
--- a/tools/metrics/actions/actions.xml
+++ b/tools/metrics/actions/actions.xml
@@ -9679,6 +9679,7 @@
 <action name="MobileMenuOpenTabs">
   <owner>aurimas@chromium.org</owner>
   <description>User pressed 'Recent tabs' in the app menu.</description>
+  <obsolete>This action was renamed to MobileMenuRecentTabs.</obsolete>
 </action>
 
 <action name="MobileMenuPrint">
@@ -9692,6 +9693,11 @@
   <obsolete>This menu item was never added to the app menu.</obsolete>
 </action>
 
+<action name="MobileMenuRecentTabs">
+  <owner>justincohen@chromium.org</owner>
+  <description>User pressed 'Recent tabs' in the app menu.</description>
+</action>
+
 <action name="MobileMenuReload">
   <owner>tedchoc@chromium.org</owner>
   <description>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index f4daa9f..4dcf9c0 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -12597,6 +12597,17 @@
   </summary>
 </histogram>
 
+<histogram name="Download.PageTransition" enum="CorePageTransition">
+  <owner>asanka@chromium.org</owner>
+  <summary>
+    The core page transition type for navigation initiated downloads. Not
+    recorded for programmatic downloads. This metric is recorded when the
+    response headers were received and processed for a download. The number of
+    samples here should correspond to Download.Counts[8] (Started) -
+    (programmatic downloads that don't have a page transition type).
+  </summary>
+</histogram>
+
 <histogram name="Download.PotentialBandwidth" units="Bytes/second">
   <obsolete>
     Deprecated January 2017.
@@ -42813,12 +42824,37 @@
   </summary>
 </histogram>
 
+<histogram name="PageLoad.Experimental.Bytes.Cache" units="KB">
+  <owner>jkarlin@chromium.org</owner>
+  <summary>
+    The number of prefiltered (e.g., compressed) KiloBytes loaded from the cache
+    via the browser process for a page load. Recorded when the page is closed.
+  </summary>
+</histogram>
+
+<histogram name="PageLoad.Experimental.Bytes.Network" units="KB">
+  <owner>jkarlin@chromium.org</owner>
+  <summary>
+    The number of prefiltered (e.g., compressed) KiloBytes loaded over the
+    network via the browser process for a page load. Recorded when the page is
+    closed.
+  </summary>
+</histogram>
+
+<histogram name="PageLoad.Experimental.Bytes.Total" units="KB">
+  <owner>jkarlin@chromium.org</owner>
+  <summary>
+    The number of prefiltered (e.g., compressed) KiloBytes loaded via the
+    browser process for a page load. Recorded when the page is closed.
+  </summary>
+</histogram>
+
 <histogram name="PageLoad.Experimental.Cache.RequestPercent.ParseStop"
     units="%">
   <owner>csharrison@chromium.org</owner>
   <summary>
-    The percent of subresources loaded from cache for the given page load.
-    Recorded at the end of HTML parsing.
+    The percent of resources loaded from cache for the given page load. Recorded
+    at the end of HTML parsing.
   </summary>
 </histogram>
 
@@ -42826,7 +42862,7 @@
     units="requests">
   <owner>csharrison@chromium.org</owner>
   <summary>
-    The number of subresources a given page finished loading from cache at parse
+    The number of resources a given page finished loading from cache at parse
     stop.
   </summary>
 </histogram>
@@ -42923,7 +42959,7 @@
     units="requests">
   <owner>csharrison@chromium.org</owner>
   <summary>
-    The number of subresources a given page finished loading at parse stop.
+    The number of resources a given page finished loading at parse stop.
   </summary>
 </histogram>
 
diff --git a/tools/perf/docs/perf_bot_sheriffing.md b/tools/perf/docs/perf_bot_sheriffing.md
index 28325f11..c907e17 100644
--- a/tools/perf/docs/perf_bot_sheriffing.md
+++ b/tools/perf/docs/perf_bot_sheriffing.md
@@ -206,14 +206,6 @@
     ensure that the bug title reflects something like "Fix and re-enable
     testname".
 4.  Investigate the failure. Some tips for investigating:
-    *   When viewing buildbot step logs, **use the **<font color="blue">[stdout]</font>** link to view logs!**.
-        This will link to logdog logs which do not expire. Do not use or link
-        to the logs found through the <font color="blue">stdio</font> link
-        whenever possible as these logs will expire.
-    *   When investigating Android, look for the logcat which is uploaded to
-        Google Storage at the end of the run. logcat will contain much more
-        detailed Android device and crash info than will be found in
-        Telemetry logs.
     *   If it's a non flaky failure, indentify the first failed
         build so you can narrow down the range of CLs that causes the failure.
         You can use the
@@ -238,6 +230,51 @@
         the logs alone. On other platforms, Devtools will produce tab
         screenshots as long as the tab did not crash.
 
+### Useful Logs and Debugging Info
+
+1. **Telemetry test runner logs**
+
+    **_Useful Content:_** Best place to start. These logs contain all of the
+    python logging information from the telemetry test runner scripts. 
+
+    **_Where to find:_** These logs can be found from the buildbot build page.
+    Click the _"[stdout]"_ link under any of the telemetry test buildbot steps
+    to view the logs. Do not use the "stdio" link which will show similiar
+    information but will expire earilier and be slower to load.
+
+2. **Android Logcat (Android)**
+
+    **_Useful Content:_** This file contains all Android device logs. All 
+    Android apps and the Android system will log information to logcat. Good
+    place to look if you believe an issue is device related
+    (Android out-of-memory problem for example). Additionally, often information
+    about native crashes will be logged to here.
+
+    **_Where to find:_** These logs can be found from the buildbot status page.
+    Click the _"logcat dump"_ link under one of the _"gsutil upload"_ steps.
+
+3. **Test Trace (Android)**
+
+    **_Useful Content:_** These logs graphically depict the start/end times for
+    all telemetry tests on all of the devices. This can help determine if test
+    failures were caused by an environmental issue.
+    (see [Cross-Device Failures](#Android-Cross-Device-Failures))
+
+    **_Where to find:_** These logs can be found from the buildbot status page.
+    Click the _"Test Trace"_ link under one of the
+    _"gsutil Upload Test Trace"_ steps.
+
+4. **Symbolized Stack Traces (Android)**
+
+    **_Useful Content:_** Contains symbolized stack traces of any Chrome or
+    Android crashes.
+
+    **_Where to find_:** These logs can be found from the buildbot status page.
+    The symbolized stack traces can be found under several steps. Click link
+    under _"symbolized breakpad crashes"_ step to see symbolized Chrome crashes.
+    Click link under _"stack tool with logcat dump"_ to see symbolized Android
+    crashes.
+
 ### Disabling Telemetry Tests
 
 If the test is a telemetry test, its name will have a '.' in it, such as
diff --git a/ui/events/blink/input_handler_proxy.cc b/ui/events/blink/input_handler_proxy.cc
index fcd5b33a..c0be74c 100644
--- a/ui/events/blink/input_handler_proxy.cc
+++ b/ui/events/blink/input_handler_proxy.cc
@@ -540,22 +540,28 @@
     return;
   }
 
+  // UMA_HISTOGRAM_ENUMERATION requires that the enum_max must be strictly
+  // greater than the sample value. kMainThreadScrollingReasonCount doesn't
+  // include the NotScrollingOnMain enum but the histograms do so adding
+  // the +1 is necessary.
+  uint32_t mainThreadScrollingReasonEnumMax =
+      cc::MainThreadScrollingReason::kMainThreadScrollingReasonCount + 1;
   if (reasons == cc::MainThreadScrollingReason::kNotScrollingOnMain) {
     if (device == blink::WebGestureDeviceTouchscreen) {
       UMA_HISTOGRAM_ENUMERATION(
           kGestureHistogramName,
           cc::MainThreadScrollingReason::kNotScrollingOnMain,
-          cc::MainThreadScrollingReason::kMainThreadScrollingReasonCount);
+          mainThreadScrollingReasonEnumMax);
     } else {
       UMA_HISTOGRAM_ENUMERATION(
           kWheelHistogramName,
           cc::MainThreadScrollingReason::kNotScrollingOnMain,
-          cc::MainThreadScrollingReason::kMainThreadScrollingReasonCount);
+          mainThreadScrollingReasonEnumMax);
     }
   }
 
   for (uint32_t i = 0;
-       i < cc::MainThreadScrollingReason::kMainThreadScrollingReasonCount - 1;
+       i < cc::MainThreadScrollingReason::kMainThreadScrollingReasonCount;
        ++i) {
     unsigned val = 1 << i;
     if (reasons & val) {
@@ -568,13 +574,11 @@
           continue;
       }
       if (device == blink::WebGestureDeviceTouchscreen) {
-        UMA_HISTOGRAM_ENUMERATION(
-            kGestureHistogramName, i + 1,
-            cc::MainThreadScrollingReason::kMainThreadScrollingReasonCount);
+        UMA_HISTOGRAM_ENUMERATION(kGestureHistogramName, i + 1,
+                                  mainThreadScrollingReasonEnumMax);
       } else {
-        UMA_HISTOGRAM_ENUMERATION(
-            kWheelHistogramName, i + 1,
-            cc::MainThreadScrollingReason::kMainThreadScrollingReasonCount);
+        UMA_HISTOGRAM_ENUMERATION(kWheelHistogramName, i + 1,
+                                  mainThreadScrollingReasonEnumMax);
       }
     }
   }
diff --git a/ui/gl/gl_image_glx.cc b/ui/gl/gl_image_glx.cc
index ba093d5..341e33d 100644
--- a/ui/gl/gl_image_glx.cc
+++ b/ui/gl/gl_image_glx.cc
@@ -124,7 +124,7 @@
 
   int config_attribs[] = {
       GLX_DRAWABLE_TYPE,                    GLX_PIXMAP_BIT,
-      GLX_BIND_TO_TEXTURE_TARGETS_EXT,      GLX_TEXTURE_2D_EXT,
+      GLX_BIND_TO_TEXTURE_TARGETS_EXT,      GLX_TEXTURE_2D_BIT_EXT,
       BindToTextureFormat(internalformat_), GL_TRUE,
       0};
   int num_elements = 0;