diff --git a/build/linux/install-chromeos-fonts.py b/build/linux/install-chromeos-fonts.py
index 71712870..61f7332 100755
--- a/build/linux/install-chromeos-fonts.py
+++ b/build/linux/install-chromeos-fonts.py
@@ -19,7 +19,10 @@
 SOURCES = [
   {
     'name': 'notofonts',
-    'version': '20160310'
+    'version': '20161129'
+  }, {
+    'name': 'noto-cjk',
+    'version': '20150910'
   }, {
     'name': 'robotofonts',
     'version': '2.132'
diff --git a/chrome/browser/component_updater/widevine_cdm_component_installer.cc b/chrome/browser/component_updater/widevine_cdm_component_installer.cc
index 5598540e..83723d2 100644
--- a/chrome/browser/component_updater/widevine_cdm_component_installer.cc
+++ b/chrome/browser/component_updater/widevine_cdm_component_installer.cc
@@ -33,7 +33,7 @@
 #include "components/component_updater/default_component_installer.h"
 #include "components/version_info/version_info.h"
 #include "content/public/browser/browser_thread.h"
-#include "content/public/browser/cdm_service.h"
+#include "content/public/browser/cdm_registry.h"
 #include "content/public/browser/plugin_service.h"
 #include "content/public/common/cdm_info.h"
 #include "content/public/common/pepper_plugin_info.h"
@@ -43,7 +43,7 @@
 #include "widevine_cdm_version.h"  // In SHARED_INTERMEDIATE_DIR. NOLINT
 
 using content::BrowserThread;
-using content::CdmService;
+using content::CdmRegistry;
 using content::PluginService;
 
 namespace component_updater {
@@ -228,14 +228,14 @@
   PluginService::GetInstance()->RefreshPlugins();
   PluginService::GetInstance()->PurgePluginListCache(NULL, false);
 
-  // Also register Widevine with the CdmService.
+  // Also register Widevine with the CdmRegistry.
   const base::FilePath cdm_path =
       GetPlatformDirectory(cdm_install_dir)
           .AppendASCII(base::GetNativeLibraryName(kWidevineCdmLibraryName));
   const std::vector<std::string> supported_codecs = base::SplitString(
       codecs, std::string(1, kCdmSupportedCodecsValueDelimiter),
       base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
-  CdmService::GetInstance()->RegisterCdm(content::CdmInfo(
+  CdmRegistry::GetInstance()->RegisterCdm(content::CdmInfo(
       kWidevineCdmType, cdm_version, cdm_path, supported_codecs));
 }
 
diff --git a/chrome/browser/fullscreen_ozone.cc b/chrome/browser/fullscreen_ozone.cc
index ad6b84e2..489fd05 100644
--- a/chrome/browser/fullscreen_ozone.cc
+++ b/chrome/browser/fullscreen_ozone.cc
@@ -6,7 +6,7 @@
 
 #include "services/service_manager/runner/common/client_util.h"
 
-bool IsFullScreenMode() {
+bool IsFullScreenMode(int64_t display_id) {
   if (service_manager::ServiceManagerIsRemote()) {
     // TODO: http://crbug.com/640390.
     NOTIMPLEMENTED();
diff --git a/chrome/browser/password_manager/auto_signin_first_run_dialog_android.h b/chrome/browser/password_manager/auto_signin_first_run_dialog_android.h
index a83d1e6..8650687 100644
--- a/chrome/browser/password_manager/auto_signin_first_run_dialog_android.h
+++ b/chrome/browser/password_manager/auto_signin_first_run_dialog_android.h
@@ -10,7 +10,6 @@
 #include "base/android/jni_android.h"
 #include "base/gtest_prod_util.h"
 #include "base/macros.h"
-#include "base/memory/scoped_vector.h"
 #include "chrome/browser/ui/passwords/manage_passwords_state.h"
 #include "content/public/browser/web_contents_observer.h"
 
diff --git a/chrome/browser/password_manager/native_backend_gnome_x.cc b/chrome/browser/password_manager/native_backend_gnome_x.cc
index 32eaea83..9dcf475 100644
--- a/chrome/browser/password_manager/native_backend_gnome_x.cc
+++ b/chrome/browser/password_manager/native_backend_gnome_x.cc
@@ -115,10 +115,10 @@
 // kept. PSL matched results get their signon_realm, origin, and action
 // rewritten to those of |lookup_form_|, with the original signon_realm saved
 // into the result's original_signon_realm data member.
-ScopedVector<PasswordForm> ConvertFormList(
+std::vector<std::unique_ptr<PasswordForm>> ConvertFormList(
     GList* found,
     const PasswordStore::FormDigest* lookup_form) {
-  ScopedVector<PasswordForm> forms;
+  std::vector<std::unique_ptr<PasswordForm>> forms;
   password_manager::PSLDomainMatchMetric psl_domain_match_metric =
       password_manager::PSL_DOMAIN_MATCH_NONE;
   const bool allow_psl_match =
@@ -233,7 +233,8 @@
 
   // Use after LoginSearch, GetLogins, GetLoginsList, GetAllLogins. Replaces the
   // content of |forms| with found logins.
-  GnomeKeyringResult WaitResult(ScopedVector<PasswordForm>* forms);
+  GnomeKeyringResult WaitResult(
+      std::vector<std::unique_ptr<PasswordForm>>* forms);
 
  private:
   struct GnomeKeyringAttributeListFreeDeleter {
@@ -269,7 +270,7 @@
 
   base::WaitableEvent event_;
   GnomeKeyringResult result_;
-  ScopedVector<PasswordForm> forms_;
+  std::vector<std::unique_ptr<PasswordForm>> forms_;
   // If the credential search is specified by a single form and needs to use
   // PSL matching, then the specifying form is stored in |lookup_form_|. If
   // PSL matching is used to find a result, then the results signon realm and
@@ -415,7 +416,8 @@
   return result_;
 }
 
-GnomeKeyringResult GKRMethod::WaitResult(ScopedVector<PasswordForm>* forms) {
+GnomeKeyringResult GKRMethod::WaitResult(
+    std::vector<std::unique_ptr<PasswordForm>>* forms) {
   DCHECK_CURRENTLY_ON(BrowserThread::DB);
   event_.Wait();
   *forms = std::move(forms_);
@@ -514,7 +516,7 @@
                           base::Bind(&GKRMethod::LoginSearch,
                                      base::Unretained(&method),
                                      form, app_string_.c_str()));
-  ScopedVector<PasswordForm> forms;
+  std::vector<std::unique_ptr<PasswordForm>> forms;
   GnomeKeyringResult result = method.WaitResult(&forms);
   if (result != GNOME_KEYRING_RESULT_OK &&
       result != GNOME_KEYRING_RESULT_NO_MATCH) {
@@ -529,7 +531,7 @@
       LOG(WARNING) << "Adding login when there are " << forms.size()
                    << " matching logins already!";
     }
-    for (const PasswordForm* old_form : forms) {
+    for (const auto& old_form : forms) {
       if (!RemoveLogin(*old_form, &temp_changes))
         return changes;
     }
@@ -559,7 +561,7 @@
                           base::Bind(&GKRMethod::LoginSearch,
                                      base::Unretained(&method),
                                      form, app_string_.c_str()));
-  ScopedVector<PasswordForm> forms;
+  std::vector<std::unique_ptr<PasswordForm>> forms;
   GnomeKeyringResult result = method.WaitResult(&forms);
   if (result == GNOME_KEYRING_RESULT_NO_MATCH)
     return true;
@@ -572,7 +574,7 @@
     return true;
 
   password_manager::PasswordStoreChangeList temp_changes;
-  for (const PasswordForm* keychain_form : forms) {
+  for (const auto& keychain_form : forms) {
     // Remove all the obsolete forms. Note that RemoveLogin can remove any form
     // matching the unique key. Thus, it's important to call it the right number
     // of times.
@@ -631,11 +633,11 @@
 bool NativeBackendGnome::DisableAutoSignInForOrigins(
     const base::Callback<bool(const GURL&)>& origin_filter,
     password_manager::PasswordStoreChangeList* changes) {
-  ScopedVector<PasswordForm> forms;
+  std::vector<std::unique_ptr<PasswordForm>> forms;
   if (!GetAllLogins(&forms))
     return false;
 
-  for (auto* form : forms) {
+  for (const std::unique_ptr<PasswordForm>& form : forms) {
     if (origin_filter.Run(form->origin) && !form->skip_zero_click) {
       form->skip_zero_click = true;
       if (!UpdateLogin(*form, changes))
@@ -646,8 +648,9 @@
   return true;
 }
 
-bool NativeBackendGnome::GetLogins(const PasswordStore::FormDigest& form,
-                                   ScopedVector<PasswordForm>* forms) {
+bool NativeBackendGnome::GetLogins(
+    const PasswordStore::FormDigest& form,
+    std::vector<std::unique_ptr<PasswordForm>>* forms) {
   DCHECK_CURRENTLY_ON(BrowserThread::DB);
   GKRMethod method;
   BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
@@ -666,16 +669,18 @@
 }
 
 bool NativeBackendGnome::GetAutofillableLogins(
-    ScopedVector<PasswordForm>* forms) {
+    std::vector<std::unique_ptr<PasswordForm>>* forms) {
   return GetLoginsList(true, forms);
 }
 
-bool NativeBackendGnome::GetBlacklistLogins(ScopedVector<PasswordForm>* forms) {
+bool NativeBackendGnome::GetBlacklistLogins(
+    std::vector<std::unique_ptr<PasswordForm>>* forms) {
   return GetLoginsList(false, forms);
 }
 
-bool NativeBackendGnome::GetLoginsList(bool autofillable,
-                                       ScopedVector<PasswordForm>* forms) {
+bool NativeBackendGnome::GetLoginsList(
+    bool autofillable,
+    std::vector<std::unique_ptr<PasswordForm>>* forms) {
   DCHECK_CURRENTLY_ON(BrowserThread::DB);
 
   uint32_t blacklisted_by_user = !autofillable;
@@ -695,7 +700,7 @@
   }
 
   // Get rid of the forms with the same sync tags.
-  ScopedVector<autofill::PasswordForm> duplicates;
+  std::vector<std::unique_ptr<PasswordForm>> duplicates;
   std::vector<std::vector<autofill::PasswordForm*>> tag_groups;
   password_manager_util::FindDuplicates(forms, &duplicates, &tag_groups);
   if (duplicates.empty())
@@ -713,7 +718,8 @@
   return true;
 }
 
-bool NativeBackendGnome::GetAllLogins(ScopedVector<PasswordForm>* forms) {
+bool NativeBackendGnome::GetAllLogins(
+    std::vector<std::unique_ptr<PasswordForm>>* forms) {
   GKRMethod method;
   BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
                           base::Bind(&GKRMethod::GetAllLogins,
@@ -730,26 +736,26 @@
   return true;
 }
 
-bool NativeBackendGnome::GetLoginsBetween(base::Time get_begin,
-                                          base::Time get_end,
-                                          TimestampToCompare date_to_compare,
-                                          ScopedVector<PasswordForm>* forms) {
+bool NativeBackendGnome::GetLoginsBetween(
+    base::Time get_begin,
+    base::Time get_end,
+    TimestampToCompare date_to_compare,
+    std::vector<std::unique_ptr<PasswordForm>>* forms) {
   DCHECK_CURRENTLY_ON(BrowserThread::DB);
   forms->clear();
   // We could walk the list and add items as we find them, but it is much
   // easier to build the list and then filter the results.
-  ScopedVector<PasswordForm> all_forms;
+  std::vector<std::unique_ptr<PasswordForm>> all_forms;
   if (!GetAllLogins(&all_forms))
     return false;
 
   base::Time PasswordForm::*date_member = date_to_compare == CREATION_TIMESTAMP
                                               ? &PasswordForm::date_created
                                               : &PasswordForm::date_synced;
-  for (auto*& saved_form : all_forms) {
-    if (get_begin <= saved_form->*date_member &&
-        (get_end.is_null() || saved_form->*date_member < get_end)) {
-      forms->push_back(saved_form);
-      saved_form = nullptr;
+  for (std::unique_ptr<PasswordForm>& saved_form : all_forms) {
+    if (get_begin <= saved_form.get()->*date_member &&
+        (get_end.is_null() || saved_form.get()->*date_member < get_end)) {
+      forms->push_back(std::move(saved_form));
     }
   }
 
@@ -766,7 +772,7 @@
   changes->clear();
   // We could walk the list and delete items as we find them, but it is much
   // easier to build the list and use RemoveLogin() to delete them.
-  ScopedVector<PasswordForm> forms;
+  std::vector<std::unique_ptr<PasswordForm>> forms;
   if (!GetLoginsBetween(get_begin, get_end, date_to_compare, &forms))
     return false;
 
diff --git a/chrome/browser/password_manager/native_backend_gnome_x.h b/chrome/browser/password_manager/native_backend_gnome_x.h
index 63edd8b..9780194 100644
--- a/chrome/browser/password_manager/native_backend_gnome_x.h
+++ b/chrome/browser/password_manager/native_backend_gnome_x.h
@@ -5,11 +5,12 @@
 #ifndef CHROME_BROWSER_PASSWORD_MANAGER_NATIVE_BACKEND_GNOME_X_H_
 #define CHROME_BROWSER_PASSWORD_MANAGER_NATIVE_BACKEND_GNOME_X_H_
 
+#include <memory>
 #include <string>
+#include <vector>
 
 #include "base/compiler_specific.h"
 #include "base/macros.h"
-#include "base/memory/scoped_vector.h"
 #include "base/time/time.h"
 #include "chrome/browser/password_manager/password_store_factory.h"
 #include "chrome/browser/password_manager/password_store_x.h"
@@ -48,12 +49,15 @@
   bool DisableAutoSignInForOrigins(
       const base::Callback<bool(const GURL&)>& origin_filter,
       password_manager::PasswordStoreChangeList* changes) override;
-  bool GetLogins(const password_manager::PasswordStore::FormDigest& form,
-                 ScopedVector<autofill::PasswordForm>* forms) override;
+  bool GetLogins(
+      const password_manager::PasswordStore::FormDigest& form,
+      std::vector<std::unique_ptr<autofill::PasswordForm>>* forms) override;
   bool GetAutofillableLogins(
-      ScopedVector<autofill::PasswordForm>* forms) override;
-  bool GetBlacklistLogins(ScopedVector<autofill::PasswordForm>* forms) override;
-  bool GetAllLogins(ScopedVector<autofill::PasswordForm>* forms) override;
+      std::vector<std::unique_ptr<autofill::PasswordForm>>* forms) override;
+  bool GetBlacklistLogins(
+      std::vector<std::unique_ptr<autofill::PasswordForm>>* forms) override;
+  bool GetAllLogins(
+      std::vector<std::unique_ptr<autofill::PasswordForm>>* forms) override;
 
  private:
   enum TimestampToCompare {
@@ -68,16 +72,16 @@
   // |autofillable|) from the keyring into |forms|, overwriting the original
   // contents of |forms|. Returns true on success.
   bool GetLoginsList(bool autofillable,
-                     ScopedVector<autofill::PasswordForm>* forms)
-      WARN_UNUSED_RESULT;
+                     std::vector<std::unique_ptr<autofill::PasswordForm>>*
+                         forms) WARN_UNUSED_RESULT;
 
   // Retrieves password created/synced in the time interval. Returns |true| if
   // the operation succeeded.
   bool GetLoginsBetween(base::Time get_begin,
                         base::Time get_end,
                         TimestampToCompare date_to_compare,
-                        ScopedVector<autofill::PasswordForm>* forms)
-      WARN_UNUSED_RESULT;
+                        std::vector<std::unique_ptr<autofill::PasswordForm>>*
+                            forms) WARN_UNUSED_RESULT;
 
   // Removes password created/synced in the time interval. Returns |true| if the
   // operation succeeded. |changes| will contain the changes applied.
diff --git a/chrome/browser/password_manager/native_backend_gnome_x_unittest.cc b/chrome/browser/password_manager/native_backend_gnome_x_unittest.cc
index 1a34312..e62dc9b 100644
--- a/chrome/browser/password_manager/native_backend_gnome_x_unittest.cc
+++ b/chrome/browser/password_manager/native_backend_gnome_x_unittest.cc
@@ -541,7 +541,7 @@
       // signon_realm. Just use a default value for now.
       target_form.signon_realm.append("Realm");
     }
-    ScopedVector<autofill::PasswordForm> form_list;
+    std::vector<std::unique_ptr<PasswordForm>> form_list;
     BrowserThread::PostTaskAndReplyWithResult(
         BrowserThread::DB,
         FROM_HERE,
@@ -590,7 +590,7 @@
     const GURL kMobileURL("http://m.facebook.com/");
     PasswordStore::FormDigest m_facebook_lookup = {
         PasswordForm::SCHEME_HTML, kMobileURL.spec(), kMobileURL};
-    ScopedVector<autofill::PasswordForm> form_list;
+    std::vector<std::unique_ptr<PasswordForm>> form_list;
     BrowserThread::PostTaskAndReplyWithResult(
         BrowserThread::DB,
         FROM_HERE,
@@ -827,7 +827,7 @@
       base::Bind(base::IgnoreResult(&NativeBackendGnome::AddLogin),
                  base::Unretained(&backend), form_google_));
 
-  ScopedVector<autofill::PasswordForm> form_list;
+  std::vector<std::unique_ptr<PasswordForm>> form_list;
   BrowserThread::PostTaskAndReplyWithResult(
       BrowserThread::DB, FROM_HERE,
       base::Bind(&NativeBackendGnome::GetAutofillableLogins,
@@ -1020,7 +1020,7 @@
                  base::Owned(new PasswordStoreChangeList), &changes));
 
   // Make sure we can still get the first form back.
-  ScopedVector<autofill::PasswordForm> form_list;
+  std::vector<std::unique_ptr<PasswordForm>> form_list;
   BrowserThread::PostTaskAndReplyWithResult(
       BrowserThread::DB, FROM_HERE,
       base::Bind(&NativeBackendGnome::GetAutofillableLogins,
@@ -1157,7 +1157,7 @@
                  PasswordStoreChangeList(1, PasswordStoreChange(
                      PasswordStoreChange::ADD, saved_android_form))));
 
-  ScopedVector<autofill::PasswordForm> form_list;
+  std::vector<std::unique_ptr<PasswordForm>> form_list;
   BrowserThread::PostTaskAndReplyWithResult(
       BrowserThread::DB, FROM_HERE,
       base::Bind(&NativeBackendGnome::GetLogins,
@@ -1263,7 +1263,7 @@
       unique_string_replacement);
 
   // Now test that GetAutofillableLogins returns only one form.
-  ScopedVector<autofill::PasswordForm> form_list;
+  std::vector<std::unique_ptr<PasswordForm>> form_list;
   BrowserThread::PostTaskAndReplyWithResult(
       BrowserThread::DB, FROM_HERE,
       base::Bind(&NativeBackendGnome::GetAutofillableLogins,
@@ -1293,7 +1293,7 @@
       base::Bind(base::IgnoreResult(&NativeBackendGnome::AddLogin),
                  base::Unretained(&backend), form_facebook_));
 
-  ScopedVector<autofill::PasswordForm> form_list;
+  std::vector<std::unique_ptr<PasswordForm>> form_list;
   BrowserThread::PostTaskAndReplyWithResult(
       BrowserThread::DB, FROM_HERE,
       base::Bind(&NativeBackendGnome::GetAllLogins, base::Unretained(&backend),
diff --git a/chrome/browser/password_manager/native_backend_kwallet_x.cc b/chrome/browser/password_manager/native_backend_kwallet_x.cc
index 21c6369..48e1953 100644
--- a/chrome/browser/password_manager/native_backend_kwallet_x.cc
+++ b/chrome/browser/password_manager/native_backend_kwallet_x.cc
@@ -7,12 +7,14 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include <iterator>
 #include <map>
 #include <utility>
 #include <vector>
 
 #include "base/bind.h"
 #include "base/logging.h"
+#include "base/memory/ptr_util.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/pickle.h"
 #include "base/stl_util.h"
@@ -114,7 +116,7 @@
                           int version,
                           bool size_32,
                           bool warn_only,
-                          ScopedVector<autofill::PasswordForm>* forms) {
+                          std::vector<std::unique_ptr<PasswordForm>>* forms) {
   base::PickleIterator iter = init_iter;
 
   size_t count = 0;
@@ -152,7 +154,7 @@
 
   // We'll swap |converted_forms| with |*forms| on success, to make sure we
   // don't return partial results on failure.
-  ScopedVector<autofill::PasswordForm> converted_forms;
+  std::vector<std::unique_ptr<PasswordForm>> converted_forms;
   converted_forms.reserve(count);
   for (size_t i = 0; i < count; ++i) {
     std::unique_ptr<PasswordForm> form(new PasswordForm());
@@ -249,11 +251,11 @@
 }
 
 // Serializes a list of PasswordForms to be stored in the wallet.
-void SerializeValue(const std::vector<autofill::PasswordForm*>& forms,
+void SerializeValue(const std::vector<std::unique_ptr<PasswordForm>>& forms,
                     base::Pickle* pickle) {
   pickle->WriteInt(kPickleVersion);
   pickle->WriteUInt64(forms.size());
-  for (autofill::PasswordForm* form : forms) {
+  for (const auto& form : forms) {
     pickle->WriteInt(form->scheme);
     pickle->WriteString(form->origin.spec());
     pickle->WriteString(form->action.spec());
@@ -281,14 +283,6 @@
   }
 }
 
-// Moves the content of |second| to the end of |first|.
-void AppendSecondToFirst(ScopedVector<autofill::PasswordForm>* first,
-                         ScopedVector<autofill::PasswordForm> second) {
-  first->reserve(first->size() + second.size());
-  first->insert(first->end(), second.begin(), second.end());
-  second.weak_clear();
-}
-
 void UMALogDeserializationStatus(bool success) {
   UMA_HISTOGRAM_BOOLEAN("PasswordManager.KWalletDeserializationStatus",
                         success);
@@ -406,14 +400,15 @@
   if (wallet_handle == kInvalidKWalletHandle)
     return password_manager::PasswordStoreChangeList();
 
-  ScopedVector<autofill::PasswordForm> forms;
+  std::vector<std::unique_ptr<PasswordForm>> forms;
   if (!GetLoginsList(form.signon_realm, wallet_handle, &forms))
     return password_manager::PasswordStoreChangeList();
 
-  auto it = std::partition(forms.begin(), forms.end(),
-                           [&form](const PasswordForm* current_form) {
-    return !ArePasswordFormUniqueKeyEqual(form, *current_form);
-  });
+  auto it = std::partition(
+      forms.begin(), forms.end(),
+      [&form](const std::unique_ptr<PasswordForm>& current_form) {
+        return !ArePasswordFormUniqueKeyEqual(form, *current_form);
+      });
   password_manager::PasswordStoreChangeList changes;
   if (it != forms.end()) {
     // It's an update.
@@ -422,11 +417,11 @@
     forms.erase(it, forms.end());
   }
 
-  forms.push_back(new PasswordForm(form));
+  forms.push_back(base::MakeUnique<PasswordForm>(form));
   changes.push_back(password_manager::PasswordStoreChange(
       password_manager::PasswordStoreChange::ADD, form));
 
-  bool ok = SetLoginsList(forms.get(), form.signon_realm, wallet_handle);
+  bool ok = SetLoginsList(forms, form.signon_realm, wallet_handle);
   if (!ok)
     changes.clear();
 
@@ -441,21 +436,22 @@
   if (wallet_handle == kInvalidKWalletHandle)
     return false;
 
-  ScopedVector<autofill::PasswordForm> forms;
+  std::vector<std::unique_ptr<PasswordForm>> forms;
   if (!GetLoginsList(form.signon_realm, wallet_handle, &forms))
     return false;
 
-  auto it = std::partition(forms.begin(), forms.end(),
-                           [&form](const PasswordForm* current_form) {
-    return !ArePasswordFormUniqueKeyEqual(form, *current_form);
-  });
+  auto it = std::partition(
+      forms.begin(), forms.end(),
+      [&form](const std::unique_ptr<PasswordForm>& current_form) {
+        return !ArePasswordFormUniqueKeyEqual(form, *current_form);
+      });
 
   if (it == forms.end())
     return true;
 
   forms.erase(it, forms.end());
-  forms.push_back(new PasswordForm(form));
-  if (SetLoginsList(forms.get(), form.signon_realm, wallet_handle)) {
+  forms.push_back(base::MakeUnique<PasswordForm>(form));
+  if (SetLoginsList(forms, form.signon_realm, wallet_handle)) {
     changes->push_back(password_manager::PasswordStoreChange(
         password_manager::PasswordStoreChange::UPDATE, form));
     return true;
@@ -472,23 +468,22 @@
   if (wallet_handle == kInvalidKWalletHandle)
     return false;
 
-  ScopedVector<autofill::PasswordForm> all_forms;
+  std::vector<std::unique_ptr<PasswordForm>> all_forms;
   if (!GetLoginsList(form.signon_realm, wallet_handle, &all_forms))
     return false;
 
-  ScopedVector<autofill::PasswordForm> kept_forms;
+  std::vector<std::unique_ptr<PasswordForm>> kept_forms;
   kept_forms.reserve(all_forms.size());
-  for (auto*& saved_form : all_forms) {
+  for (std::unique_ptr<PasswordForm>& saved_form : all_forms) {
     if (!ArePasswordFormUniqueKeyEqual(form, *saved_form)) {
-      kept_forms.push_back(saved_form);
-      saved_form = nullptr;
+      kept_forms.push_back(std::move(saved_form));
     }
   }
 
   if (kept_forms.size() != all_forms.size()) {
     changes->push_back(password_manager::PasswordStoreChange(
         password_manager::PasswordStoreChange::REMOVE, form));
-    return SetLoginsList(kept_forms.get(), form.signon_realm, wallet_handle);
+    return SetLoginsList(kept_forms, form.signon_realm, wallet_handle);
   }
 
   return true;
@@ -512,11 +507,11 @@
 bool NativeBackendKWallet::DisableAutoSignInForOrigins(
     const base::Callback<bool(const GURL&)>& origin_filter,
     password_manager::PasswordStoreChangeList* changes) {
-  ScopedVector<autofill::PasswordForm> all_forms;
+  std::vector<std::unique_ptr<PasswordForm>> all_forms;
   if (!GetAllLogins(&all_forms))
     return false;
 
-  for (auto* form : all_forms) {
+  for (const std::unique_ptr<PasswordForm>& form : all_forms) {
     if (origin_filter.Run(form->origin) && !form->skip_zero_click) {
       form->skip_zero_click = true;
       if (!UpdateLogin(*form, changes))
@@ -528,7 +523,7 @@
 
 bool NativeBackendKWallet::GetLogins(
     const password_manager::PasswordStore::FormDigest& form,
-    ScopedVector<autofill::PasswordForm>* forms) {
+    std::vector<std::unique_ptr<PasswordForm>>* forms) {
   int wallet_handle = WalletHandle();
   if (wallet_handle == kInvalidKWalletHandle)
     return false;
@@ -536,7 +531,7 @@
 }
 
 bool NativeBackendKWallet::GetAutofillableLogins(
-    ScopedVector<autofill::PasswordForm>* forms) {
+    std::vector<std::unique_ptr<PasswordForm>>* forms) {
   int wallet_handle = WalletHandle();
   if (wallet_handle == kInvalidKWalletHandle)
     return false;
@@ -544,7 +539,7 @@
 }
 
 bool NativeBackendKWallet::GetBlacklistLogins(
-    ScopedVector<autofill::PasswordForm>* forms) {
+    std::vector<std::unique_ptr<PasswordForm>>* forms) {
   int wallet_handle = WalletHandle();
   if (wallet_handle == kInvalidKWalletHandle)
     return false;
@@ -552,7 +547,7 @@
 }
 
 bool NativeBackendKWallet::GetAllLogins(
-    ScopedVector<autofill::PasswordForm>* forms) {
+    std::vector<std::unique_ptr<PasswordForm>>* forms) {
   int wallet_handle = WalletHandle();
   if (wallet_handle == kInvalidKWalletHandle)
     return false;
@@ -562,7 +557,7 @@
 bool NativeBackendKWallet::GetLoginsList(
     const std::string& signon_realm,
     int wallet_handle,
-    ScopedVector<autofill::PasswordForm>* forms) {
+    std::vector<std::unique_ptr<PasswordForm>>* forms) {
   forms->clear();
   // Is there an entry in the wallet?
   bool has_entry = false;
@@ -598,43 +593,45 @@
 bool NativeBackendKWallet::GetLoginsList(
     BlacklistOptions options,
     int wallet_handle,
-    ScopedVector<autofill::PasswordForm>* forms) {
+    std::vector<std::unique_ptr<PasswordForm>>* forms) {
   forms->clear();
-  ScopedVector<autofill::PasswordForm> all_forms;
+  std::vector<std::unique_ptr<PasswordForm>> all_forms;
   if (!GetAllLoginsInternal(wallet_handle, &all_forms))
     return false;
 
   // Remove the duplicate sync tags.
-  ScopedVector<autofill::PasswordForm> duplicates;
+  std::vector<std::unique_ptr<PasswordForm>> duplicates;
   password_manager_util::FindDuplicates(&all_forms, &duplicates, nullptr);
   if (!duplicates.empty()) {
     // Fill the signon realms to be updated.
-    std::map<std::string, std::vector<autofill::PasswordForm*>> update_forms;
-    for (autofill::PasswordForm* form : duplicates) {
+    std::map<std::string, std::vector<std::unique_ptr<PasswordForm>>>
+        update_forms;
+    for (const auto& form : duplicates) {
       update_forms.insert(std::make_pair(
-          form->signon_realm, std::vector<autofill::PasswordForm*>()));
+          form->signon_realm, std::vector<std::unique_ptr<PasswordForm>>()));
     }
 
     // Fill the actual forms to be saved.
-    for (autofill::PasswordForm* form : all_forms) {
+    for (const auto& form : all_forms) {
       auto it = update_forms.find(form->signon_realm);
       if (it != update_forms.end())
-        it->second.push_back(form);
+        it->second.push_back(base::MakeUnique<PasswordForm>(*form));
     }
 
     // Update the backend.
-    for (const auto& forms : update_forms) {
-      if (!SetLoginsList(forms.second, forms.first, wallet_handle))
+    for (const auto& update_forms_for_realm : update_forms) {
+      if (!SetLoginsList(update_forms_for_realm.second,
+                         update_forms_for_realm.first, wallet_handle)) {
         return false;
+      }
     }
   }
   // We have to read all the entries, and then filter them here.
   forms->reserve(all_forms.size());
-  for (auto*& saved_form : all_forms) {
+  for (std::unique_ptr<PasswordForm>& saved_form : all_forms) {
     if (saved_form->blacklisted_by_user ==
         (options == BlacklistOptions::BLACKLISTED)) {
-      forms->push_back(saved_form);
-      saved_form = nullptr;
+      forms->push_back(std::move(saved_form));
     }
   }
 
@@ -643,7 +640,7 @@
 
 bool NativeBackendKWallet::GetAllLoginsInternal(
     int wallet_handle,
-    ScopedVector<autofill::PasswordForm>* forms) {
+    std::vector<std::unique_ptr<PasswordForm>>* forms) {
   // We could probably also use readEntryList here.
   std::vector<std::string> realm_list;
   KWalletDBus::Error error = kwallet_dbus_.EntryList(
@@ -665,13 +662,17 @@
     // Can't we all just agree on whether bytes are signed or not? Please?
     base::Pickle pickle(reinterpret_cast<const char*>(bytes.data()),
                         bytes.size());
-    AppendSecondToFirst(forms, DeserializeValue(signon_realm, pickle));
+    std::vector<std::unique_ptr<PasswordForm>> from_pickle =
+        DeserializeValue(signon_realm, pickle);
+    forms->reserve(forms->size() + from_pickle.size());
+    std::move(from_pickle.begin(), from_pickle.end(),
+              std::back_inserter(*forms));
   }
   return true;
 }
 
 bool NativeBackendKWallet::SetLoginsList(
-    const std::vector<autofill::PasswordForm*>& forms,
+    const std::vector<std::unique_ptr<PasswordForm>>& forms,
     const std::string& signon_realm,
     int wallet_handle) {
   if (forms.empty()) {
@@ -733,27 +734,26 @@
     // Can't we all just agree on whether bytes are signed or not? Please?
     base::Pickle pickle(reinterpret_cast<const char*>(bytes.data()),
                         bytes.size());
-    ScopedVector<autofill::PasswordForm> all_forms =
+    std::vector<std::unique_ptr<PasswordForm>> all_forms =
         DeserializeValue(signon_realm, pickle);
 
-    ScopedVector<autofill::PasswordForm> kept_forms;
+    std::vector<std::unique_ptr<PasswordForm>> kept_forms;
     kept_forms.reserve(all_forms.size());
-    base::Time autofill::PasswordForm::*date_member =
-        date_to_compare == CREATION_TIMESTAMP
-            ? &autofill::PasswordForm::date_created
-            : &autofill::PasswordForm::date_synced;
-    for (auto*& saved_form : all_forms) {
-      if (delete_begin <= saved_form->*date_member &&
-          (delete_end.is_null() || saved_form->*date_member < delete_end)) {
+    base::Time PasswordForm::*date_member =
+        date_to_compare == CREATION_TIMESTAMP ? &PasswordForm::date_created
+                                              : &PasswordForm::date_synced;
+    for (std::unique_ptr<PasswordForm>& saved_form : all_forms) {
+      if (delete_begin <= saved_form.get()->*date_member &&
+          (delete_end.is_null() ||
+           saved_form.get()->*date_member < delete_end)) {
         changes->push_back(password_manager::PasswordStoreChange(
             password_manager::PasswordStoreChange::REMOVE, *saved_form));
       } else {
-        kept_forms.push_back(saved_form);
-        saved_form = nullptr;
+        kept_forms.push_back(std::move(saved_form));
       }
     }
 
-    if (!SetLoginsList(kept_forms.get(), signon_realm, wallet_handle)) {
+    if (!SetLoginsList(kept_forms, signon_realm, wallet_handle)) {
       ok = false;
       changes->clear();
     }
@@ -762,9 +762,9 @@
 }
 
 // static
-ScopedVector<autofill::PasswordForm> NativeBackendKWallet::DeserializeValue(
-    const std::string& signon_realm,
-    const base::Pickle& pickle) {
+std::vector<std::unique_ptr<PasswordForm>>
+NativeBackendKWallet::DeserializeValue(const std::string& signon_realm,
+                                       const base::Pickle& pickle) {
   base::PickleIterator iter(pickle);
 
   int version = -1;
@@ -772,10 +772,10 @@
       version < 0 || version > kPickleVersion) {
     LOG(ERROR) << "Failed to deserialize KWallet entry "
                << "(realm: " << signon_realm << ")";
-    return ScopedVector<autofill::PasswordForm>();
+    return std::vector<std::unique_ptr<PasswordForm>>();
   }
 
-  ScopedVector<autofill::PasswordForm> forms;
+  std::vector<std::unique_ptr<PasswordForm>> forms;
   bool success = true;
   if (version > 0) {
     // In current pickles, we expect 64-bit sizes. Failure is an error.
diff --git a/chrome/browser/password_manager/native_backend_kwallet_x.h b/chrome/browser/password_manager/native_backend_kwallet_x.h
index 0efa4fc..d92a911 100644
--- a/chrome/browser/password_manager/native_backend_kwallet_x.h
+++ b/chrome/browser/password_manager/native_backend_kwallet_x.h
@@ -5,13 +5,13 @@
 #ifndef CHROME_BROWSER_PASSWORD_MANAGER_NATIVE_BACKEND_KWALLET_X_H_
 #define CHROME_BROWSER_PASSWORD_MANAGER_NATIVE_BACKEND_KWALLET_X_H_
 
+#include <memory>
 #include <string>
 #include <vector>
 
 #include "base/compiler_specific.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
-#include "base/memory/scoped_vector.h"
 #include "base/nix/xdg_util.h"
 #include "base/time/time.h"
 #include "chrome/browser/password_manager/password_store_factory.h"
@@ -56,12 +56,15 @@
   bool DisableAutoSignInForOrigins(
       const base::Callback<bool(const GURL&)>& origin_filter,
       password_manager::PasswordStoreChangeList* changes) override;
-  bool GetLogins(const password_manager::PasswordStore::FormDigest& form,
-                 ScopedVector<autofill::PasswordForm>* forms) override;
+  bool GetLogins(
+      const password_manager::PasswordStore::FormDigest& form,
+      std::vector<std::unique_ptr<autofill::PasswordForm>>* forms) override;
   bool GetAutofillableLogins(
-      ScopedVector<autofill::PasswordForm>* forms) override;
-  bool GetBlacklistLogins(ScopedVector<autofill::PasswordForm>* forms) override;
-  bool GetAllLogins(ScopedVector<autofill::PasswordForm>* forms) override;
+      std::vector<std::unique_ptr<autofill::PasswordForm>>* forms) override;
+  bool GetBlacklistLogins(
+      std::vector<std::unique_ptr<autofill::PasswordForm>>* forms) override;
+  bool GetAllLogins(
+      std::vector<std::unique_ptr<autofill::PasswordForm>>* forms) override;
 
  protected:
   // Invalid handle returned by WalletHandle().
@@ -71,7 +74,7 @@
   bool InitWithBus(scoped_refptr<dbus::Bus> optional_bus);
 
   // Deserializes a list of PasswordForms from the wallet.
-  static ScopedVector<autofill::PasswordForm> DeserializeValue(
+  static std::vector<std::unique_ptr<autofill::PasswordForm>> DeserializeValue(
       const std::string& signon_realm,
       const base::Pickle& pickle);
 
@@ -99,27 +102,29 @@
   // true on success.
   bool GetLoginsList(const std::string& signon_realm,
                      int wallet_handle,
-                     ScopedVector<autofill::PasswordForm>* forms)
-      WARN_UNUSED_RESULT;
+                     std::vector<std::unique_ptr<autofill::PasswordForm>>*
+                         forms) WARN_UNUSED_RESULT;
 
   // Overwrites |forms| with all credentials matching |options|. Returns true on
   // success.
   bool GetLoginsList(BlacklistOptions options,
                      int wallet_handle,
-                     ScopedVector<autofill::PasswordForm>* forms)
-      WARN_UNUSED_RESULT;
+                     std::vector<std::unique_ptr<autofill::PasswordForm>>*
+                         forms) WARN_UNUSED_RESULT;
 
   // Overwrites |forms| with all stored credentials. Returns true on success.
-  bool GetAllLoginsInternal(int wallet_handle,
-                            ScopedVector<autofill::PasswordForm>* forms)
+  bool GetAllLoginsInternal(
+      int wallet_handle,
+      std::vector<std::unique_ptr<autofill::PasswordForm>>* forms)
       WARN_UNUSED_RESULT;
 
   // Writes a list of PasswordForms to the wallet with the given signon_realm.
   // Overwrites any existing list for this signon_realm. Removes the entry if
   // |forms| is empty. Returns true on success.
-  bool SetLoginsList(const std::vector<autofill::PasswordForm*>& forms,
-                     const std::string& signon_realm,
-                     int wallet_handle);
+  bool SetLoginsList(
+      const std::vector<std::unique_ptr<autofill::PasswordForm>>& forms,
+      const std::string& signon_realm,
+      int wallet_handle);
 
   // Removes password created/synced in the time interval. Returns |true| if the
   // operation succeeded. |changes| will contain the changes applied.
diff --git a/chrome/browser/password_manager/native_backend_kwallet_x_unittest.cc b/chrome/browser/password_manager/native_backend_kwallet_x_unittest.cc
index 7aaece0..76ac3cb 100644
--- a/chrome/browser/password_manager/native_backend_kwallet_x_unittest.cc
+++ b/chrome/browser/password_manager/native_backend_kwallet_x_unittest.cc
@@ -137,7 +137,7 @@
 // value is false.
 void CheckGetAutofillableLoginsFails(
     PasswordStoreX::NativeBackend* backend,
-    ScopedVector<autofill::PasswordForm>* forms) {
+    std::vector<std::unique_ptr<PasswordForm>>* forms) {
   EXPECT_FALSE(backend->GetAutofillableLogins(forms));
 }
 
@@ -663,7 +663,7 @@
     EXPECT_TRUE(wallet_.readEntry(folder, entries[i], &value));
     base::Pickle pickle(reinterpret_cast<const char*>(value.data()),
                         value.size());
-    ScopedVector<autofill::PasswordForm> forms =
+    std::vector<std::unique_ptr<PasswordForm>> forms =
         NativeBackendKWalletStub::DeserializeValue(entries[i], pickle);
     const std::vector<const PasswordForm*>& expect = sorted_expected[i].second;
     EXPECT_EQ(expect.size(), forms.size());
@@ -779,7 +779,7 @@
       base::Bind(base::IgnoreResult(&NativeBackendKWalletStub::AddLogin),
                  base::Unretained(&backend), form_google_));
 
-  ScopedVector<autofill::PasswordForm> form_list;
+  std::vector<std::unique_ptr<PasswordForm>> form_list;
   BrowserThread::PostTaskAndReplyWithResult(
       BrowserThread::DB, FROM_HERE,
       base::Bind(&NativeBackendKWalletStub::GetAutofillableLogins,
@@ -899,7 +899,7 @@
                  base::Owned(new PasswordStoreChangeList), &changes));
 
   // Make sure we can still get the first form back.
-  ScopedVector<autofill::PasswordForm> form_list;
+  std::vector<std::unique_ptr<PasswordForm>> form_list;
   BrowserThread::PostTaskAndReplyWithResult(
       BrowserThread::DB, FROM_HERE,
       base::Bind(&NativeBackendKWalletStub::GetAutofillableLogins,
@@ -975,7 +975,7 @@
                  PasswordStoreChangeList(1, PasswordStoreChange(
                      PasswordStoreChange::ADD, saved_android_form))));
 
-  ScopedVector<autofill::PasswordForm> form_list;
+  std::vector<std::unique_ptr<PasswordForm>> form_list;
   BrowserThread::PostTaskAndReplyWithResult(
       BrowserThread::DB, FROM_HERE,
       base::Bind(&NativeBackendKWalletStub::GetLogins,
@@ -1083,7 +1083,7 @@
   wallet_.writeEntry("Chrome Form Data (42)", form_google_.signon_realm, value);
 
   // Now test that GetAutofillableLogins returns only one form.
-  ScopedVector<autofill::PasswordForm> form_list;
+  std::vector<std::unique_ptr<PasswordForm>> form_list;
   BrowserThread::PostTaskAndReplyWithResult(
       BrowserThread::DB, FROM_HERE,
       base::Bind(&NativeBackendKWalletStub::GetAutofillableLogins,
@@ -1118,7 +1118,7 @@
                       PasswordStoreChange::ADD, form_google_))));
 
   // Verify that nothing is in fact returned, because KWallet fails to respond.
-  ScopedVector<autofill::PasswordForm> form_list;
+  std::vector<std::unique_ptr<PasswordForm>> form_list;
   BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
                           base::Bind(&CheckGetAutofillableLoginsFails,
                                      base::Unretained(&backend), &form_list));
@@ -1139,7 +1139,7 @@
       base::Bind(base::IgnoreResult(&NativeBackendKWalletStub::AddLogin),
                  base::Unretained(&backend), form_isc_));
 
-  ScopedVector<autofill::PasswordForm> form_list;
+  std::vector<std::unique_ptr<PasswordForm>> form_list;
   BrowserThread::PostTaskAndReplyWithResult(
       BrowserThread::DB, FROM_HERE,
       base::Bind(&NativeBackendKWalletStub::GetAllLogins,
@@ -1247,7 +1247,7 @@
   PasswordForm form = form_google_;
 
   CreateVersion1PlusPickle(form, &pickle, 9, 9);
-  ScopedVector<PasswordForm> form_list =
+  std::vector<std::unique_ptr<PasswordForm>> form_list =
       NativeBackendKWalletStub::DeserializeValue(form.signon_realm, pickle);
   EXPECT_EQ(1u, form_list.size());
   if (form_list.size() > 0)
@@ -1262,7 +1262,7 @@
   // Version 8 pickles deserialize with their own 'skip_zero_click' value.
   form.skip_zero_click = false;
   CreateVersion1PlusPickle(form, &pickle, 8, 8);
-  ScopedVector<PasswordForm> form_list =
+  std::vector<std::unique_ptr<PasswordForm>> form_list =
       NativeBackendKWalletStub::DeserializeValue(form.signon_realm, pickle);
   EXPECT_EQ(1u, form_list.size());
   if (form_list.size() > 0)
@@ -1277,7 +1277,7 @@
   // Version 7 pickles always deserialize with 'skip_zero_click' of 'true'.
   form.skip_zero_click = false;
   CreateVersion1PlusPickle(form, &pickle, 7, 7);
-  ScopedVector<PasswordForm> form_list =
+  std::vector<std::unique_ptr<PasswordForm>> form_list =
       NativeBackendKWalletStub::DeserializeValue(form.signon_realm, pickle);
   EXPECT_EQ(1u, form_list.size());
   form.skip_zero_click = true;
@@ -1295,7 +1295,7 @@
   }
   CreateVersion1PlusPickle(form, &pickle, 6, with_optional_field ? 7 : 5);
 
-  ScopedVector<PasswordForm> form_list =
+  std::vector<std::unique_ptr<PasswordForm>> form_list =
       NativeBackendKWalletStub::DeserializeValue(form.signon_realm, pickle);
 
   EXPECT_EQ(1u, form_list.size());
@@ -1311,7 +1311,7 @@
   form.generation_upload_status = default_values.generation_upload_status;
   CreateVersion1PlusPickle(form, &pickle, 6, 6);
 
-  ScopedVector<PasswordForm> form_list =
+  std::vector<std::unique_ptr<PasswordForm>> form_list =
       NativeBackendKWalletStub::DeserializeValue(form.signon_realm, pickle);
 
   EXPECT_EQ(1u, form_list.size());
@@ -1331,7 +1331,7 @@
   form.generation_upload_status = default_values.generation_upload_status;
   CreateVersion1PlusPickle(form, &pickle, 3, 3);
 
-  ScopedVector<PasswordForm> form_list =
+  std::vector<std::unique_ptr<PasswordForm>> form_list =
       NativeBackendKWalletStub::DeserializeValue(form.signon_realm, pickle);
 
   EXPECT_EQ(1u, form_list.size());
@@ -1347,7 +1347,7 @@
   form.form_data = form_google_.form_data;
   CreateVersion1PlusPickle(form, &pickle, 2, 2);
 
-  ScopedVector<PasswordForm> form_list =
+  std::vector<std::unique_ptr<PasswordForm>> form_list =
       NativeBackendKWalletStub::DeserializeValue(form.signon_realm, pickle);
 
   EXPECT_EQ(1u, form_list.size());
@@ -1361,7 +1361,7 @@
   PasswordForm form = form_google_;
   CreateVersion1PlusPickle(form, &pickle, 1, 1);
 
-  ScopedVector<autofill::PasswordForm> form_list =
+  std::vector<std::unique_ptr<PasswordForm>> form_list =
       NativeBackendKWalletStub::DeserializeValue(form.signon_realm, pickle);
 
   // This will match |old_form_google_| because not all the fields present in
@@ -1377,7 +1377,7 @@
   PasswordForm form = old_form_google_;
   form.scheme = scheme;
   CreateVersion0Pickle(size_32, form, &pickle);
-  ScopedVector<autofill::PasswordForm> form_list =
+  std::vector<std::unique_ptr<PasswordForm>> form_list =
       NativeBackendKWalletStub::DeserializeValue(form.signon_realm, pickle);
   EXPECT_EQ(1u, form_list.size());
   if (form_list.size() > 0)
diff --git a/chrome/browser/password_manager/native_backend_libsecret.cc b/chrome/browser/password_manager/native_backend_libsecret.cc
index 82976c21..dd21a65 100644
--- a/chrome/browser/password_manager/native_backend_libsecret.cc
+++ b/chrome/browser/password_manager/native_backend_libsecret.cc
@@ -180,7 +180,7 @@
   // on origin_url, username_element, username_value, password_element and
   // signon_realm first, remove that, and then add the new entry.
   password_manager::PasswordStoreChangeList changes;
-  ScopedVector<autofill::PasswordForm> forms;
+  std::vector<std::unique_ptr<PasswordForm>> forms;
   if (!AddUpdateLoginSearch(form, &forms))
     return changes;
 
@@ -190,7 +190,7 @@
       LOG(WARNING) << "Adding login when there are " << forms.size()
                    << " matching logins already!";
     }
-    for (const PasswordForm* old_form : forms) {
+    for (const auto& old_form : forms) {
       if (!RemoveLogin(*old_form, &temp_changes))
         return changes;
     }
@@ -214,7 +214,7 @@
   // then add the new entry. We'd add the new one first, and then delete the
   // original, but then the delete might actually delete the newly-added entry!
   DCHECK(changes);
-  ScopedVector<autofill::PasswordForm> forms;
+  std::vector<std::unique_ptr<PasswordForm>> forms;
   if (!AddUpdateLoginSearch(form, &forms))
     return false;
   if (forms.empty())
@@ -223,7 +223,7 @@
     return true;
 
   password_manager::PasswordStoreChangeList temp_changes;
-  for (const PasswordForm* keychain_form : forms) {
+  for (const auto& keychain_form : forms) {
     // Remove all the obsolete forms. Note that RemoveLogin can remove any form
     // matching the unique key. Thus, it's important to call it the right number
     // of times.
@@ -241,7 +241,7 @@
 }
 
 bool NativeBackendLibsecret::RemoveLogin(
-    const autofill::PasswordForm& form,
+    const PasswordForm& form,
     password_manager::PasswordStoreChangeList* changes) {
   DCHECK(changes);
   GError* error = nullptr;
@@ -283,11 +283,11 @@
 bool NativeBackendLibsecret::DisableAutoSignInForOrigins(
     const base::Callback<bool(const GURL&)>& origin_filter,
     password_manager::PasswordStoreChangeList* changes) {
-  ScopedVector<autofill::PasswordForm> all_forms;
+  std::vector<std::unique_ptr<PasswordForm>> all_forms;
   if (!GetLoginsList(nullptr, ALL_LOGINS, &all_forms))
     return false;
 
-  for (auto* form : all_forms) {
+  for (const std::unique_ptr<PasswordForm>& form : all_forms) {
     if (origin_filter.Run(form->origin) && !form->skip_zero_click) {
       form->skip_zero_click = true;
       if (!UpdateLogin(*form, changes))
@@ -300,13 +300,13 @@
 
 bool NativeBackendLibsecret::GetLogins(
     const PasswordStore::FormDigest& form,
-    ScopedVector<autofill::PasswordForm>* forms) {
+    std::vector<std::unique_ptr<PasswordForm>>* forms) {
   return GetLoginsList(&form, ALL_LOGINS, forms);
 }
 
 bool NativeBackendLibsecret::AddUpdateLoginSearch(
-    const autofill::PasswordForm& lookup_form,
-    ScopedVector<autofill::PasswordForm>* forms) {
+    const PasswordForm& lookup_form,
+    std::vector<std::unique_ptr<PasswordForm>>* forms) {
   if (!ensured_keyring_unlocked_) {
     LibsecretLoader::EnsureKeyringUnlocked();
     ensured_keyring_unlocked_ = true;
@@ -395,24 +395,24 @@
 }
 
 bool NativeBackendLibsecret::GetAutofillableLogins(
-    ScopedVector<autofill::PasswordForm>* forms) {
+    std::vector<std::unique_ptr<PasswordForm>>* forms) {
   return GetLoginsList(nullptr, AUTOFILLABLE_LOGINS, forms);
 }
 
 bool NativeBackendLibsecret::GetBlacklistLogins(
-    ScopedVector<autofill::PasswordForm>* forms) {
+    std::vector<std::unique_ptr<PasswordForm>>* forms) {
   return GetLoginsList(nullptr, BLACKLISTED_LOGINS, forms);
 }
 
 bool NativeBackendLibsecret::GetAllLogins(
-    ScopedVector<autofill::PasswordForm>* forms) {
+    std::vector<std::unique_ptr<PasswordForm>>* forms) {
   return GetLoginsList(nullptr, ALL_LOGINS, forms);
 }
 
 bool NativeBackendLibsecret::GetLoginsList(
     const PasswordStore::FormDigest* lookup_form,
     GetLoginsListOptions options,
-    ScopedVector<autofill::PasswordForm>* forms) {
+    std::vector<std::unique_ptr<PasswordForm>>* forms) {
   if (!ensured_keyring_unlocked_) {
     LibsecretLoader::EnsureKeyringUnlocked();
     ensured_keyring_unlocked_ = true;
@@ -449,8 +449,8 @@
     return true;
 
   // Get rid of the forms with the same sync tags.
-  ScopedVector<autofill::PasswordForm> duplicates;
-  std::vector<std::vector<autofill::PasswordForm*>> tag_groups;
+  std::vector<std::unique_ptr<PasswordForm>> duplicates;
+  std::vector<std::vector<PasswordForm*>> tag_groups;
   password_manager_util::FindDuplicates(forms, &duplicates, &tag_groups);
   if (duplicates.empty())
     return true;
@@ -471,21 +471,19 @@
     base::Time get_begin,
     base::Time get_end,
     TimestampToCompare date_to_compare,
-    ScopedVector<autofill::PasswordForm>* forms) {
+    std::vector<std::unique_ptr<PasswordForm>>* forms) {
   forms->clear();
-  ScopedVector<autofill::PasswordForm> all_forms;
+  std::vector<std::unique_ptr<PasswordForm>> all_forms;
   if (!GetLoginsList(nullptr, ALL_LOGINS, &all_forms))
     return false;
 
-  base::Time autofill::PasswordForm::*date_member =
-      date_to_compare == CREATION_TIMESTAMP
-          ? &autofill::PasswordForm::date_created
-          : &autofill::PasswordForm::date_synced;
-  for (auto*& saved_form : all_forms) {
-    if (get_begin <= saved_form->*date_member &&
-        (get_end.is_null() || saved_form->*date_member < get_end)) {
-      forms->push_back(saved_form);
-      saved_form = nullptr;
+  base::Time PasswordForm::*date_member = date_to_compare == CREATION_TIMESTAMP
+                                              ? &PasswordForm::date_created
+                                              : &PasswordForm::date_synced;
+  for (std::unique_ptr<PasswordForm>& saved_form : all_forms) {
+    if (get_begin <= saved_form.get()->*date_member &&
+        (get_end.is_null() || saved_form.get()->*date_member < get_end)) {
+      forms->push_back(std::move(saved_form));
     }
   }
 
@@ -499,7 +497,7 @@
     password_manager::PasswordStoreChangeList* changes) {
   DCHECK(changes);
   changes->clear();
-  ScopedVector<autofill::PasswordForm> forms;
+  std::vector<std::unique_ptr<PasswordForm>> forms;
   if (!GetLoginsBetween(get_begin, get_end, date_to_compare, &forms))
     return false;
 
@@ -510,10 +508,11 @@
   return true;
 }
 
-ScopedVector<autofill::PasswordForm> NativeBackendLibsecret::ConvertFormList(
+std::vector<std::unique_ptr<PasswordForm>>
+NativeBackendLibsecret::ConvertFormList(
     GList* found,
     const PasswordStore::FormDigest* lookup_form) {
-  ScopedVector<autofill::PasswordForm> forms;
+  std::vector<std::unique_ptr<PasswordForm>> forms;
   password_manager::PSLDomainMatchMetric psl_domain_match_metric =
       password_manager::PSL_DOMAIN_MATCH_NONE;
   GError* error = nullptr;
diff --git a/chrome/browser/password_manager/native_backend_libsecret.h b/chrome/browser/password_manager/native_backend_libsecret.h
index 082f3649..f6e06c6 100644
--- a/chrome/browser/password_manager/native_backend_libsecret.h
+++ b/chrome/browser/password_manager/native_backend_libsecret.h
@@ -5,11 +5,12 @@
 #ifndef CHROME_BROWSER_PASSWORD_MANAGER_NATIVE_BACKEND_LIBSECRET_H_
 #define CHROME_BROWSER_PASSWORD_MANAGER_NATIVE_BACKEND_LIBSECRET_H_
 
+#include <memory>
 #include <string>
+#include <vector>
 
 #include "base/compiler_specific.h"
 #include "base/macros.h"
-#include "base/memory/scoped_vector.h"
 #include "base/time/time.h"
 #include "chrome/browser/password_manager/password_store_factory.h"
 #include "chrome/browser/password_manager/password_store_x.h"
@@ -46,12 +47,15 @@
   bool DisableAutoSignInForOrigins(
       const base::Callback<bool(const GURL&)>& origin_filter,
       password_manager::PasswordStoreChangeList* changes) override;
-  bool GetLogins(const password_manager::PasswordStore::FormDigest& form,
-                 ScopedVector<autofill::PasswordForm>* forms) override;
+  bool GetLogins(
+      const password_manager::PasswordStore::FormDigest& form,
+      std::vector<std::unique_ptr<autofill::PasswordForm>>* forms) override;
   bool GetAutofillableLogins(
-      ScopedVector<autofill::PasswordForm>* forms) override;
-  bool GetBlacklistLogins(ScopedVector<autofill::PasswordForm>* forms) override;
-  bool GetAllLogins(ScopedVector<autofill::PasswordForm>* forms) override;
+      std::vector<std::unique_ptr<autofill::PasswordForm>>* forms) override;
+  bool GetBlacklistLogins(
+      std::vector<std::unique_ptr<autofill::PasswordForm>>* forms) override;
+  bool GetAllLogins(
+      std::vector<std::unique_ptr<autofill::PasswordForm>>* forms) override;
 
  private:
   enum TimestampToCompare {
@@ -62,7 +66,7 @@
   // Returns credentials matching |lookup_form| via |forms|.
   bool AddUpdateLoginSearch(
       const autofill::PasswordForm& lookup_form,
-      ScopedVector<autofill::PasswordForm>* forms);
+      std::vector<std::unique_ptr<autofill::PasswordForm>>* forms);
 
   // Adds a login form without checking for one to replace first.
   bool RawAddLogin(const autofill::PasswordForm& form);
@@ -79,15 +83,16 @@
   bool GetLoginsList(
       const password_manager::PasswordStore::FormDigest* lookup_form,
       GetLoginsListOptions options,
-      ScopedVector<autofill::PasswordForm>* forms) WARN_UNUSED_RESULT;
+      std::vector<std::unique_ptr<autofill::PasswordForm>>* forms)
+      WARN_UNUSED_RESULT;
 
   // Retrieves password created/synced in the time interval into |forms|,
   // overwriting the original contents of |forms|. Returns true on success.
   bool GetLoginsBetween(base::Time get_begin,
                         base::Time get_end,
                         TimestampToCompare date_to_compare,
-                        ScopedVector<autofill::PasswordForm>* forms)
-      WARN_UNUSED_RESULT;
+                        std::vector<std::unique_ptr<autofill::PasswordForm>>*
+                            forms) WARN_UNUSED_RESULT;
 
   // Removes password created/synced in the time interval. Returns |true| if the
   // operation succeeded. |changes| will contain the changes applied.
@@ -98,7 +103,7 @@
 
   // Convert data get from Libsecret to Passwordform. Uses |lookup_form| for
   // additional (PSL) matching, if present.
-  ScopedVector<autofill::PasswordForm> ConvertFormList(
+  std::vector<std::unique_ptr<autofill::PasswordForm>> ConvertFormList(
       GList* found,
       const password_manager::PasswordStore::FormDigest* lookup_form);
 
diff --git a/chrome/browser/password_manager/native_backend_libsecret_unittest.cc b/chrome/browser/password_manager/native_backend_libsecret_unittest.cc
index 32a6d70..132f4ce0 100644
--- a/chrome/browser/password_manager/native_backend_libsecret_unittest.cc
+++ b/chrome/browser/password_manager/native_backend_libsecret_unittest.cc
@@ -47,13 +47,12 @@
 };
 
 struct MockSecretItem {
-  MockSecretValue* value;
+  std::unique_ptr<MockSecretValue> value;
   GHashTable* attributes;
 
-  MockSecretItem(MockSecretValue* value, GHashTable* attributes)
-      : value(value), attributes(attributes) {}
+  MockSecretItem(std::unique_ptr<MockSecretValue> value, GHashTable* attributes)
+      : value(std::move(value)), attributes(attributes) {}
   ~MockSecretItem() {
-    delete value;
     g_hash_table_destroy(attributes);
   }
 
@@ -87,7 +86,7 @@
 }
 
 // The list of all libsecret items we have stored.
-ScopedVector<MockSecretItem>* global_mock_libsecret_items;
+std::vector<std::unique_ptr<MockSecretItem>>* global_mock_libsecret_items;
 bool global_mock_libsecret_reject_local_ids = false;
 
 gboolean mock_secret_password_store_sync(const SecretSchema* schema,
@@ -120,9 +119,8 @@
     g_hash_table_insert(attributes, g_strdup(name), value);
   }
   va_end(ap);
-  MockSecretValue* secret_value = new MockSecretValue(g_strdup(password));
-  MockSecretItem* item = new MockSecretItem(secret_value, attributes);
-  global_mock_libsecret_items->push_back(item);
+  global_mock_libsecret_items->push_back(base::MakeUnique<MockSecretItem>(
+      base::MakeUnique<MockSecretValue>(g_strdup(password)), attributes));
   return true;
 }
 
@@ -134,9 +132,9 @@
                                        GError** error) {
   EXPECT_TRUE(flags & SECRET_SEARCH_UNLOCK);
   GList* result = nullptr;
-  for (MockSecretItem* item : *global_mock_libsecret_items) {
-    if (Matches(item, attributes))
-      result = g_list_append(result, item);
+  for (std::unique_ptr<MockSecretItem>& item : *global_mock_libsecret_items) {
+    if (Matches(item.get(), attributes))
+      result = g_list_append(result, item.get());
   }
   return result;
 }
@@ -165,12 +163,11 @@
   }
   va_end(ap);
 
-  ScopedVector<MockSecretItem> kept_mock_libsecret_items;
+  std::vector<std::unique_ptr<MockSecretItem>> kept_mock_libsecret_items;
   kept_mock_libsecret_items.reserve(global_mock_libsecret_items->size());
-  for (auto*& item : *global_mock_libsecret_items) {
-    if (!Matches(item, attributes)) {
-      kept_mock_libsecret_items.push_back(item);
-      item = nullptr;
+  for (std::unique_ptr<MockSecretItem>& item : *global_mock_libsecret_items) {
+    if (!Matches(item.get(), attributes)) {
+      kept_mock_libsecret_items.push_back(std::move(item));
     }
   }
   global_mock_libsecret_items->swap(kept_mock_libsecret_items);
@@ -181,7 +178,8 @@
 }
 
 SecretValue* mock_secret_item_get_secret(SecretItem* self) {
-  MockSecretValue* mock_value = reinterpret_cast<MockSecretItem*>(self)->value;
+  MockSecretValue* mock_value =
+      reinterpret_cast<MockSecretItem*>(self)->value.get();
   return reinterpret_cast<SecretValue*>(mock_value);
 }
 
@@ -437,12 +435,12 @@
       // signon_realm. Just use a default value for now.
       target_form.signon_realm.append("Realm");
     }
-    ScopedVector<autofill::PasswordForm> form_list;
+    std::vector<std::unique_ptr<PasswordForm>> form_list;
     EXPECT_TRUE(backend.GetLogins(target_form, &form_list));
 
     EXPECT_EQ(1u, global_mock_libsecret_items->size());
     if (!global_mock_libsecret_items->empty())
-      CheckMockSecretItem((*global_mock_libsecret_items)[0], credentials,
+      CheckMockSecretItem((*global_mock_libsecret_items)[0].get(), credentials,
                           "chrome-321");
     global_mock_libsecret_items->clear();
 
@@ -468,7 +466,7 @@
     const GURL kMobileURL("http://m.facebook.com/");
     PasswordStore::FormDigest m_facebook_lookup = {
         PasswordForm::SCHEME_HTML, kMobileURL.spec(), kMobileURL};
-    ScopedVector<autofill::PasswordForm> form_list;
+    std::vector<std::unique_ptr<PasswordForm>> form_list;
     EXPECT_TRUE(backend.GetLogins(m_facebook_lookup, &form_list));
 
     EXPECT_EQ(1u, global_mock_libsecret_items->size());
@@ -584,7 +582,7 @@
 
     EXPECT_EQ(1u, global_mock_libsecret_items->size());
     if (!global_mock_libsecret_items->empty() > 0)
-      CheckMockSecretItem((*global_mock_libsecret_items)[0], form_isc_,
+      CheckMockSecretItem((*global_mock_libsecret_items)[0].get(), form_isc_,
                           "chrome-42");
 
     // Remove form_isc_.
@@ -607,7 +605,7 @@
   PasswordForm form_isc_;
   PasswordForm other_auth_;
 
-  ScopedVector<MockSecretItem> mock_libsecret_items_;
+  std::vector<std::unique_ptr<MockSecretItem>> mock_libsecret_items_;
 };
 
 TEST_F(NativeBackendLibsecretTest, BasicAddLogin) {
@@ -617,7 +615,7 @@
 
   EXPECT_EQ(1u, global_mock_libsecret_items->size());
   if (!global_mock_libsecret_items->empty())
-    CheckMockSecretItem((*global_mock_libsecret_items)[0], form_google_,
+    CheckMockSecretItem((*global_mock_libsecret_items)[0].get(), form_google_,
                         "chrome-42");
 }
 
@@ -626,7 +624,7 @@
 
   VerifiedAdd(&backend, form_google_);
 
-  ScopedVector<autofill::PasswordForm> form_list;
+  std::vector<std::unique_ptr<PasswordForm>> form_list;
   EXPECT_TRUE(backend.GetAutofillableLogins(&form_list));
 
   ASSERT_EQ(1u, form_list.size());
@@ -634,7 +632,7 @@
 
   EXPECT_EQ(1u, global_mock_libsecret_items->size());
   if (!global_mock_libsecret_items->empty())
-    CheckMockSecretItem((*global_mock_libsecret_items)[0], form_google_,
+    CheckMockSecretItem((*global_mock_libsecret_items)[0].get(), form_google_,
                         "chrome-42");
 }
 
@@ -644,7 +642,7 @@
   VerifiedAdd(&backend, form_google_);
   VerifiedAdd(&backend, form_facebook_);
 
-  ScopedVector<autofill::PasswordForm> form_list;
+  std::vector<std::unique_ptr<PasswordForm>> form_list;
   EXPECT_TRUE(backend.GetAllLogins(&form_list));
 
   ASSERT_EQ(2u, form_list.size());
@@ -713,7 +711,7 @@
 
   EXPECT_EQ(1u, global_mock_libsecret_items->size());
   if (!global_mock_libsecret_items->empty()) {
-    CheckMockSecretItem((*global_mock_libsecret_items)[0], form_google_,
+    CheckMockSecretItem((*global_mock_libsecret_items)[0].get(), form_google_,
                         "chrome-42");
   }
 
@@ -722,8 +720,8 @@
 
   EXPECT_EQ(1u, global_mock_libsecret_items->size());
   if (!global_mock_libsecret_items->empty())
-    CheckMockSecretItem((*global_mock_libsecret_items)[0], new_form_google,
-                        "chrome-42");
+    CheckMockSecretItem((*global_mock_libsecret_items)[0].get(),
+                        new_form_google, "chrome-42");
 }
 
 TEST_F(NativeBackendLibsecretTest, BasicRemoveLogin) {
@@ -733,7 +731,7 @@
 
   EXPECT_EQ(1u, global_mock_libsecret_items->size());
   if (!global_mock_libsecret_items->empty())
-    CheckMockSecretItem((*global_mock_libsecret_items)[0], form_google_,
+    CheckMockSecretItem((*global_mock_libsecret_items)[0].get(), form_google_,
                         "chrome-42");
 
   VerifiedRemove(&backend, form_google_);
@@ -749,7 +747,7 @@
 
   EXPECT_EQ(1u, global_mock_libsecret_items->size());
   if (!global_mock_libsecret_items->empty())
-    CheckMockSecretItem((*global_mock_libsecret_items)[0], form_google_,
+    CheckMockSecretItem((*global_mock_libsecret_items)[0].get(), form_google_,
                         "chrome-42");
 
   // Action url match not required for removal.
@@ -767,7 +765,7 @@
 
   EXPECT_EQ(1u, global_mock_libsecret_items->size());
   if (!global_mock_libsecret_items->empty())
-    CheckMockSecretItem((*global_mock_libsecret_items)[0], form_google_,
+    CheckMockSecretItem((*global_mock_libsecret_items)[0].get(), form_google_,
                         "chrome-42");
 
   // Attempt to remove a login that doesn't exist.
@@ -776,7 +774,7 @@
   CheckPasswordChanges(PasswordStoreChangeList(), changes);
 
   // Make sure we can still get the first form back.
-  ScopedVector<autofill::PasswordForm> form_list;
+  std::vector<std::unique_ptr<PasswordForm>> form_list;
   EXPECT_TRUE(backend.GetAutofillableLogins(&form_list));
 
   // Quick check that we got something back.
@@ -785,7 +783,7 @@
 
   EXPECT_EQ(1u, global_mock_libsecret_items->size());
   if (!global_mock_libsecret_items->empty())
-    CheckMockSecretItem((*global_mock_libsecret_items)[0], form_google_,
+    CheckMockSecretItem((*global_mock_libsecret_items)[0].get(), form_google_,
                         "chrome-42");
 }
 
@@ -797,7 +795,7 @@
 
   EXPECT_EQ(1u, global_mock_libsecret_items->size());
   if (!global_mock_libsecret_items->empty()) {
-    CheckMockSecretItem((*global_mock_libsecret_items)[0], form_google_,
+    CheckMockSecretItem((*global_mock_libsecret_items)[0].get(), form_google_,
                         "chrome-42");
   }
 
@@ -808,7 +806,7 @@
 
   EXPECT_EQ(1u, global_mock_libsecret_items->size());
   if (!global_mock_libsecret_items->empty())
-    CheckMockSecretItem((*global_mock_libsecret_items)[0], form_google_,
+    CheckMockSecretItem((*global_mock_libsecret_items)[0].get(), form_google_,
                         "chrome-42");
 }
 
@@ -819,7 +817,7 @@
 
   EXPECT_EQ(1u, global_mock_libsecret_items->size());
   if (!global_mock_libsecret_items->empty()) {
-    CheckMockSecretItem((*global_mock_libsecret_items)[0], form_google_,
+    CheckMockSecretItem((*global_mock_libsecret_items)[0].get(), form_google_,
                         "chrome-42");
   }
 
@@ -830,7 +828,7 @@
 
   EXPECT_EQ(1u, global_mock_libsecret_items->size());
   if (!global_mock_libsecret_items->empty()) {
-    CheckMockSecretItem((*global_mock_libsecret_items)[0], form_google_,
+    CheckMockSecretItem((*global_mock_libsecret_items)[0].get(), form_google_,
                         "chrome-42");
   }
 }
@@ -853,7 +851,7 @@
 
   EXPECT_EQ(1u, global_mock_libsecret_items->size());
   if (!global_mock_libsecret_items->empty())
-    CheckMockSecretItem((*global_mock_libsecret_items)[0], form_google_,
+    CheckMockSecretItem((*global_mock_libsecret_items)[0].get(), form_google_,
                         "chrome-42");
 }
 
@@ -872,7 +870,7 @@
 
   VerifiedAdd(&backend, saved_android_form);
 
-  ScopedVector<autofill::PasswordForm> form_list;
+  std::vector<std::unique_ptr<PasswordForm>> form_list;
   EXPECT_TRUE(backend.GetAutofillableLogins(&form_list));
 
   EXPECT_EQ(1u, form_list.size());
@@ -897,8 +895,8 @@
   VerifiedAdd(&backend, form_facebook_);
 
   EXPECT_EQ(2u, global_mock_libsecret_items->size());
-  for (auto* item : *global_mock_libsecret_items)
-    CheckUint32Attribute(item, "should_skip_zero_click", 0);
+  for (const auto& item : *global_mock_libsecret_items)
+    CheckUint32Attribute(item.get(), "should_skip_zero_click", 0);
 
   // Set the canonical forms to the updated value for the following comparison.
   form_google_.skip_zero_click = true;
@@ -915,13 +913,13 @@
   CheckPasswordChanges(expected_changes, changes);
 
   EXPECT_EQ(2u, global_mock_libsecret_items->size());
-  CheckStringAttribute((*global_mock_libsecret_items)[0],
-                       "origin_url", form_google_.origin.spec());
-  CheckUint32Attribute((*global_mock_libsecret_items)[0],
+  CheckStringAttribute((*global_mock_libsecret_items)[0].get(), "origin_url",
+                       form_google_.origin.spec());
+  CheckUint32Attribute((*global_mock_libsecret_items)[0].get(),
                        "should_skip_zero_click", 0);
-  CheckStringAttribute((*global_mock_libsecret_items)[1],
-                       "origin_url", form_facebook_.origin.spec());
-  CheckUint32Attribute((*global_mock_libsecret_items)[1],
+  CheckStringAttribute((*global_mock_libsecret_items)[1].get(), "origin_url",
+                       form_facebook_.origin.spec());
+  CheckUint32Attribute((*global_mock_libsecret_items)[1].get(),
                        "should_skip_zero_click", 1);
 }
 
@@ -937,7 +935,7 @@
   // Remove an integer attribute.
   (*global_mock_libsecret_items)[0]->RemoveAttribute("times_used");
 
-  ScopedVector<autofill::PasswordForm> form_list;
+  std::vector<std::unique_ptr<PasswordForm>> form_list;
   EXPECT_TRUE(backend.GetAutofillableLogins(&form_list));
 
   EXPECT_EQ(1u, form_list.size());
@@ -970,7 +968,7 @@
   strncpy(substr, unique_string_replacement, strlen(unique_string));
 
   // Now test that GetAutofillableLogins returns only one form.
-  ScopedVector<autofill::PasswordForm> form_list;
+  std::vector<std::unique_ptr<PasswordForm>> form_list;
   EXPECT_TRUE(backend.GetAutofillableLogins(&form_list));
 
   EXPECT_EQ(1u, form_list.size());
@@ -978,7 +976,7 @@
 
   EXPECT_EQ(1u, global_mock_libsecret_items->size());
   if (!global_mock_libsecret_items->empty()) {
-    CheckMockSecretItem((*global_mock_libsecret_items)[0], form_google_,
+    CheckMockSecretItem((*global_mock_libsecret_items)[0].get(), form_google_,
                         "chrome-42");
   }
 }
diff --git a/chrome/browser/password_manager/password_store_mac.cc b/chrome/browser/password_manager/password_store_mac.cc
index 5d377405..bd6e204 100644
--- a/chrome/browser/password_manager/password_store_mac.cc
+++ b/chrome/browser/password_manager/password_store_mac.cc
@@ -7,6 +7,7 @@
 #include <CoreServices/CoreServices.h>
 #include <stddef.h>
 #include <algorithm>
+#include <iterator>
 #include <set>
 #include <string>
 #include <utility>
@@ -187,29 +188,29 @@
 }
 
 PasswordStoreChangeList FormsToRemoveChangeList(
-    const std::vector<PasswordForm*>& forms) {
+    const std::vector<std::unique_ptr<PasswordForm>>& forms) {
   PasswordStoreChangeList changes;
-  for (std::vector<PasswordForm*>::const_iterator i = forms.begin();
-       i != forms.end(); ++i) {
-    changes.push_back(PasswordStoreChange(PasswordStoreChange::REMOVE, **i));
+  for (const auto& form : forms) {
+    changes.push_back(PasswordStoreChange(PasswordStoreChange::REMOVE, *form));
   }
   return changes;
 }
 
 // Moves the content of |second| to the end of |first|.
-void AppendSecondToFirst(ScopedVector<autofill::PasswordForm>* first,
-                         ScopedVector<autofill::PasswordForm>* second) {
-  first->insert(first->end(), second->begin(), second->end());
-  second->weak_clear();
+void AppendSecondToFirst(std::vector<std::unique_ptr<PasswordForm>>* first,
+                         std::vector<std::unique_ptr<PasswordForm>>* second) {
+  first->reserve(first->size() + second->size());
+  std::move(second->begin(), second->end(), std::back_inserter(*first));
+  second->clear();
 }
 
 // Returns the best match for |base_form| from |keychain_forms|, or nullptr if
 // there is no suitable match.
 const PasswordForm* BestKeychainFormForForm(
     const PasswordForm& base_form,
-    const std::vector<PasswordForm*>& keychain_forms) {
+    const std::vector<std::unique_ptr<PasswordForm>>& keychain_forms) {
   const PasswordForm* partial_match = nullptr;
-  for (const auto* keychain_form : keychain_forms) {
+  for (const auto& keychain_form : keychain_forms) {
     // TODO(stuartmorgan): We should really be scoring path matches and picking
     // the best, rather than just checking exact-or-not (although in practice
     // keychain items with paths probably came from us).
@@ -217,49 +218,19 @@
             base_form, *keychain_form,
             internal_keychain_helpers::FUZZY_FORM_MATCH)) {
       if (base_form.origin == keychain_form->origin) {
-        return keychain_form;
+        return keychain_form.get();
       } else if (!partial_match) {
-        partial_match = keychain_form;
+        partial_match = keychain_form.get();
       }
     }
   }
   return partial_match;
 }
 
-// Iterates over all elements in |forms|, passes the pointed to objects to
-// |mover|, and clears |forms| efficiently. FormMover needs to be a callable
-// entity, accepting std::unique_ptr<autofill::PasswordForm> as its sole
-// argument.
-template <typename FormMover>
-inline void MoveAllFormsOut(ScopedVector<autofill::PasswordForm>* forms,
-                            FormMover mover) {
-  for (autofill::PasswordForm* form_ptr : *forms) {
-    mover(std::unique_ptr<autofill::PasswordForm>(form_ptr));
-  }
-  // We moved the ownership of every form out of |forms|. For performance
-  // reasons, we can just weak_clear it, instead of nullptr-ing the respective
-  // elements and letting the vector's destructor to go through the list once
-  // more. This was tested on a benchmark, and seemed to make a difference on
-  // Mac.
-  forms->weak_clear();
-}
-
 // True if the form has no password to be stored in Keychain.
-bool IsLoginDatabaseOnlyForm(const autofill::PasswordForm& form) {
+bool IsLoginDatabaseOnlyForm(const PasswordForm& form) {
   return form.blacklisted_by_user || !form.federation_origin.unique() ||
-         form.scheme == autofill::PasswordForm::SCHEME_USERNAME_ONLY;
-}
-
-// TODO(crbug.com/555132): Temporary utility to convert from std::vector to
-// ScopedVector.
-ScopedVector<PasswordForm> ConvertToScopedVector(
-    std::vector<std::unique_ptr<PasswordForm>> forms) {
-  ScopedVector<PasswordForm> result;
-  result.resize(forms.size());
-  std::transform(
-      forms.begin(), forms.end(), result.begin(),
-      [](std::unique_ptr<PasswordForm>& form) { return form.release(); });
-  return result;
+         form.scheme == PasswordForm::SCHEME_USERNAME_ONLY;
 }
 
 }  // namespace
@@ -503,17 +474,20 @@
 // Moves entries from |forms| that represent either blacklisted or federated
 // logins into |extracted|. These two types are stored only in the LoginDatabase
 // and do not have corresponding Keychain entries.
-void ExtractNonKeychainForms(ScopedVector<autofill::PasswordForm>* forms,
-                             ScopedVector<autofill::PasswordForm>* extracted) {
+void ExtractNonKeychainForms(
+    std::vector<std::unique_ptr<PasswordForm>>* forms,
+    std::vector<std::unique_ptr<PasswordForm>>* extracted) {
   extracted->reserve(extracted->size() + forms->size());
-  ScopedVector<autofill::PasswordForm> remaining;
-  MoveAllFormsOut(forms, [&remaining, extracted](
-                             std::unique_ptr<autofill::PasswordForm> form) {
+
+  std::vector<std::unique_ptr<PasswordForm>> remaining;
+  remaining.reserve(forms->size());
+
+  for (std::unique_ptr<PasswordForm>& form : *forms) {
     if (IsLoginDatabaseOnlyForm(*form))
       extracted->push_back(std::move(form));
     else
       remaining.push_back(std::move(form));
-  });
+  }
   forms->swap(remaining);
 }
 
@@ -526,44 +500,41 @@
 // The database forms of type (2) have their password value updated from the
 // corresponding keychain form, and all the keychain forms corresponding to some
 // database form are removed from |keychain_forms| and deleted.
-void MergePasswordForms(ScopedVector<autofill::PasswordForm>* keychain_forms,
-                        ScopedVector<autofill::PasswordForm>* database_forms,
-                        ScopedVector<autofill::PasswordForm>* merged_forms) {
+void MergePasswordForms(
+    std::vector<std::unique_ptr<PasswordForm>>* keychain_forms,
+    std::vector<std::unique_ptr<PasswordForm>>* database_forms,
+    std::vector<std::unique_ptr<PasswordForm>>* merged_forms) {
   // Pull out the database blacklist items and federated logins, since they are
   // used as-is rather than being merged with keychain forms.
   ExtractNonKeychainForms(database_forms, merged_forms);
 
   // Merge the normal entries.
-  ScopedVector<autofill::PasswordForm> unused_database_forms;
+  std::vector<std::unique_ptr<PasswordForm>> unused_database_forms;
   unused_database_forms.reserve(database_forms->size());
-  std::set<const autofill::PasswordForm*> used_keychain_forms;
+  std::set<const PasswordForm*> used_keychain_forms;
   // Move all database forms to either |merged_forms| or
   // |unused_database_forms|, based on whether they have a match in the keychain
   // forms or not. If there is a match, add its password to the DB form and
   // mark the keychain form as used.
-  MoveAllFormsOut(
-      database_forms,
-      [keychain_forms, &used_keychain_forms, merged_forms,
-       &unused_database_forms](std::unique_ptr<autofill::PasswordForm> form) {
-        const PasswordForm* best_match =
-            BestKeychainFormForForm(*form, keychain_forms->get());
-        if (best_match) {
-          used_keychain_forms.insert(best_match);
-          form->password_value = best_match->password_value;
-          merged_forms->push_back(std::move(form));
-        } else {
-          unused_database_forms.push_back(std::move(form));
-        }
-      });
+  for (std::unique_ptr<PasswordForm>& db_form : *database_forms) {
+    const PasswordForm* best_match =
+        BestKeychainFormForForm(*db_form, *keychain_forms);
+    if (best_match) {
+      used_keychain_forms.insert(best_match);
+      db_form->password_value = best_match->password_value;
+      merged_forms->push_back(std::move(db_form));
+    } else {
+      unused_database_forms.push_back(std::move(db_form));
+    }
+  }
   database_forms->swap(unused_database_forms);
 
   // Clear out all the Keychain entries we used.
-  ScopedVector<autofill::PasswordForm> unused_keychain_forms;
+  std::vector<std::unique_ptr<PasswordForm>> unused_keychain_forms;
   unused_keychain_forms.reserve(keychain_forms->size());
-  for (auto*& keychain_form : *keychain_forms) {
-    if (!base::ContainsKey(used_keychain_forms, keychain_form)) {
-      unused_keychain_forms.push_back(keychain_form);
-      keychain_form = nullptr;
+  for (std::unique_ptr<PasswordForm>& keychain_form : *keychain_forms) {
+    if (!base::ContainsKey(used_keychain_forms, keychain_form.get())) {
+      unused_keychain_forms.push_back(std::move(keychain_form));
     }
   }
   keychain_forms->swap(unused_keychain_forms);
@@ -588,9 +559,10 @@
   return item_form_pairs;
 }
 
-void GetPasswordsForForms(const AppleKeychain& keychain,
-                          ScopedVector<autofill::PasswordForm>* database_forms,
-                          ScopedVector<autofill::PasswordForm>* passwords) {
+void GetPasswordsForForms(
+    const AppleKeychain& keychain,
+    std::vector<std::unique_ptr<PasswordForm>>* database_forms,
+    std::vector<std::unique_ptr<PasswordForm>>* passwords) {
   // First load the attributes of all items in the keychain without loading
   // their password data, and then match items in |database_forms| against them.
   // This avoids individually searching through the keychain for passwords
@@ -606,22 +578,19 @@
   // Next, compare the attributes of the PasswordForms in |database_forms|
   // against those in |item_form_pairs|, and extract password data for each
   // matching PasswordForm using its corresponding SecKeychainItemRef.
-  ScopedVector<autofill::PasswordForm> unused_db_forms;
+  std::vector<std::unique_ptr<PasswordForm>> unused_db_forms;
   unused_db_forms.reserve(database_forms->size());
   // Move database forms with a password stored in |keychain| to |passwords|,
   // including the password. The rest is moved to |unused_db_forms|.
-  MoveAllFormsOut(
-      database_forms,
-      [&keychain, &item_form_pairs, passwords,
-       &unused_db_forms](std::unique_ptr<autofill::PasswordForm> form) {
-        ScopedVector<autofill::PasswordForm> keychain_matches =
-            ExtractPasswordsMergeableWithForm(keychain, item_form_pairs, *form);
+  for (std::unique_ptr<PasswordForm>& db_form : *database_forms) {
+    std::vector<std::unique_ptr<PasswordForm>> keychain_matches =
+        ExtractPasswordsMergeableWithForm(keychain, item_form_pairs, *db_form);
 
-        ScopedVector<autofill::PasswordForm> db_form_container;
-        db_form_container.push_back(std::move(form));
-        MergePasswordForms(&keychain_matches, &db_form_container, passwords);
-        AppendSecondToFirst(&unused_db_forms, &db_form_container);
-      });
+    std::vector<std::unique_ptr<PasswordForm>> db_form_container;
+    db_form_container.push_back(std::move(db_form));
+    MergePasswordForms(&keychain_matches, &db_form_container, passwords);
+    AppendSecondToFirst(&unused_db_forms, &db_form_container);
+  }
   database_forms->swap(unused_db_forms);
 
   for (SecKeychainItemRef item : keychain_items) {
@@ -684,17 +653,17 @@
   return FormsMatchForMerge(query_form, other_form, STRICT_FORM_MATCH);
 }
 
-ScopedVector<autofill::PasswordForm> ExtractPasswordsMergeableWithForm(
+std::vector<std::unique_ptr<PasswordForm>> ExtractPasswordsMergeableWithForm(
     const AppleKeychain& keychain,
     const std::vector<ItemFormPair>& item_form_pairs,
     const PasswordForm& query_form) {
-  ScopedVector<autofill::PasswordForm> matches;
+  std::vector<std::unique_ptr<PasswordForm>> matches;
   for (std::vector<ItemFormPair>::const_iterator i = item_form_pairs.begin();
        i != item_form_pairs.end(); ++i) {
     if (FormIsValidAndMatchesOtherForm(query_form, *(i->second))) {
       // Create a new object, since the caller is responsible for deleting the
       // returned forms.
-      std::unique_ptr<PasswordForm> form_with_password(new PasswordForm());
+      auto form_with_password = base::MakeUnique<PasswordForm>();
       FillPasswordFormFromKeychainItem(
           keychain, i->first, form_with_password.get(),
           true);  // Load password attributes and data.
@@ -715,7 +684,7 @@
     : keychain_(keychain), finds_only_owned_(false) {
 }
 
-ScopedVector<autofill::PasswordForm>
+std::vector<std::unique_ptr<PasswordForm>>
 MacKeychainPasswordFormAdapter::PasswordsFillingForm(
     const std::string& signon_realm,
     PasswordForm::Scheme scheme) {
@@ -773,7 +742,7 @@
   return matches;
 }
 
-ScopedVector<autofill::PasswordForm>
+std::vector<std::unique_ptr<PasswordForm>>
 MacKeychainPasswordFormAdapter::GetAllPasswordFormPasswords() {
   std::vector<SecKeychainItemRef> items = GetAllPasswordFormKeychainItems();
   return ConvertKeychainItemsToForms(&items);
@@ -840,12 +809,12 @@
   finds_only_owned_ = finds_only_owned;
 }
 
-ScopedVector<autofill::PasswordForm>
+std::vector<std::unique_ptr<PasswordForm>>
 MacKeychainPasswordFormAdapter::ConvertKeychainItemsToForms(
     std::vector<SecKeychainItemRef>* items) {
-  ScopedVector<autofill::PasswordForm> forms;
+  std::vector<std::unique_ptr<PasswordForm>> forms;
   for (SecKeychainItemRef item : *items) {
-    std::unique_ptr<PasswordForm> form(new PasswordForm());
+    auto form = base::MakeUnique<PasswordForm>();
     if (internal_keychain_helpers::FillPasswordFormFromKeychainItem(
             *keychain_, item, form.get(), true)) {
       forms.push_back(std::move(form));
@@ -884,10 +853,11 @@
 }
 
 std::vector<SecKeychainItemRef>
-    MacKeychainPasswordFormAdapter::MatchingKeychainItems(
-        const std::string& signon_realm,
-        autofill::PasswordForm::Scheme scheme,
-        const char* path, const char* username) {
+MacKeychainPasswordFormAdapter::MatchingKeychainItems(
+    const std::string& signon_realm,
+    PasswordForm::Scheme scheme,
+    const char* path,
+    const char* username) {
   std::vector<SecKeychainItemRef> matches;
 
   std::string server;
@@ -984,13 +954,11 @@
 PasswordStoreMac::MigrationResult PasswordStoreMac::ImportFromKeychain(
     password_manager::LoginDatabase* login_db,
     crypto::AppleKeychain* keychain) {
-  std::vector<std::unique_ptr<PasswordForm>> database_forms_new_format;
-  if (!login_db->GetAutofillableLogins(&database_forms_new_format))
+  std::vector<std::unique_ptr<PasswordForm>> database_forms;
+  if (!login_db->GetAutofillableLogins(&database_forms))
     return LOGIN_DB_FAILURE;
-  ScopedVector<PasswordForm> database_forms =
-      ConvertToScopedVector(std::move(database_forms_new_format));
 
-  ScopedVector<PasswordForm> uninteresting_forms;
+  std::vector<std::unique_ptr<PasswordForm>> uninteresting_forms;
   internal_keychain_helpers::ExtractNonKeychainForms(&database_forms,
                                                      &uninteresting_forms);
   // If there are no passwords to lookup in the Keychain then we're done.
@@ -1020,13 +988,13 @@
   // matching PasswordForm using its corresponding SecKeychainItemRef.
   size_t unmerged_forms_count = 0;
   login_db->set_clear_password_values(false);
-  for (PasswordForm* form : database_forms) {
-    ScopedVector<autofill::PasswordForm> keychain_matches =
+  for (const auto& form : database_forms) {
+    std::vector<std::unique_ptr<PasswordForm>> keychain_matches =
         internal_keychain_helpers::ExtractPasswordsMergeableWithForm(
             *keychain, item_form_pairs, *form);
 
     const PasswordForm* best_match =
-        BestKeychainFormForForm(*form, keychain_matches.get());
+        BestKeychainFormForForm(*form, keychain_matches);
     if (best_match) {
       form->password_value = best_match->password_value;
       PasswordStoreChangeList change = login_db->UpdateLogin(*form);
@@ -1054,7 +1022,7 @@
 // static
 void PasswordStoreMac::CleanUpKeychain(
     crypto::AppleKeychain* keychain,
-    const std::vector<std::unique_ptr<autofill::PasswordForm>>& forms) {
+    const std::vector<std::unique_ptr<PasswordForm>>& forms) {
   MacKeychainPasswordFormAdapter keychain_adapter(keychain);
   keychain_adapter.SetFindsOnlyOwnedItems(true);
   for (const auto& form : forms)
@@ -1147,23 +1115,20 @@
     base::Time delete_begin,
     base::Time delete_end) {
   PasswordStoreChangeList changes;
-  ScopedVector<PasswordForm> forms_to_consider;
-  ScopedVector<PasswordForm> forms_to_remove;
+  std::vector<std::unique_ptr<PasswordForm>> forms_to_consider;
+  std::vector<std::unique_ptr<PasswordForm>> forms_to_remove;
   if (login_metadata_db_ &&
       login_metadata_db_->GetLoginsCreatedBetween(delete_begin, delete_end,
                                                   &forms_to_consider)) {
-    MoveAllFormsOut(
-        &forms_to_consider,
-        [this, &url_filter, &forms_to_remove](
-            std::unique_ptr<autofill::PasswordForm> form_to_consider) {
-          if (url_filter.Run(form_to_consider->origin) &&
-              login_metadata_db_->RemoveLogin(*form_to_consider))
-            forms_to_remove.push_back(std::move(form_to_consider));
-        });
+    for (std::unique_ptr<PasswordForm>& form_to_consider : forms_to_consider) {
+      if (url_filter.Run(form_to_consider->origin) &&
+          login_metadata_db_->RemoveLogin(*form_to_consider))
+        forms_to_remove.push_back(std::move(form_to_consider));
+    }
     if (!forms_to_remove.empty()) {
-      RemoveKeychainForms(forms_to_remove.get());
+      RemoveKeychainForms(forms_to_remove);
       CleanOrphanedForms(&forms_to_remove);  // Add the orphaned forms.
-      changes = FormsToRemoveChangeList(forms_to_remove.get());
+      changes = FormsToRemoveChangeList(forms_to_remove);
       LogStatsForBulkDeletion(changes.size());
     }
   }
@@ -1174,15 +1139,15 @@
     base::Time delete_begin,
     base::Time delete_end) {
   PasswordStoreChangeList changes;
-  ScopedVector<PasswordForm> forms_to_remove;
+  std::vector<std::unique_ptr<PasswordForm>> forms_to_remove;
   if (login_metadata_db_ &&
       login_metadata_db_->GetLoginsCreatedBetween(delete_begin, delete_end,
                                                   &forms_to_remove) &&
       login_metadata_db_->RemoveLoginsCreatedBetween(delete_begin,
                                                      delete_end)) {
-    RemoveKeychainForms(forms_to_remove.get());
+    RemoveKeychainForms(forms_to_remove);
     CleanOrphanedForms(&forms_to_remove);  // Add the orphaned forms.
-    changes = FormsToRemoveChangeList(forms_to_remove.get());
+    changes = FormsToRemoveChangeList(forms_to_remove);
     LogStatsForBulkDeletion(changes.size());
   }
   return changes;
@@ -1192,14 +1157,14 @@
     base::Time delete_begin,
     base::Time delete_end) {
   PasswordStoreChangeList changes;
-  ScopedVector<PasswordForm> forms_to_remove;
+  std::vector<std::unique_ptr<PasswordForm>> forms_to_remove;
   if (login_metadata_db_ &&
       login_metadata_db_->GetLoginsSyncedBetween(delete_begin, delete_end,
                                                  &forms_to_remove) &&
       login_metadata_db_->RemoveLoginsSyncedBetween(delete_begin, delete_end)) {
-    RemoveKeychainForms(forms_to_remove.get());
+    RemoveKeychainForms(forms_to_remove);
     CleanOrphanedForms(&forms_to_remove);  // Add the orphaned forms_to_remove.
-    changes = FormsToRemoveChangeList(forms_to_remove.get());
+    changes = FormsToRemoveChangeList(forms_to_remove);
     LogStatsForBulkDeletionDuringRollback(changes.size());
   }
   return changes;
@@ -1207,7 +1172,7 @@
 
 PasswordStoreChangeList PasswordStoreMac::DisableAutoSignInForOriginsImpl(
     const base::Callback<bool(const GURL&)>& origin_filter) {
-  ScopedVector<autofill::PasswordForm> forms;
+  std::vector<std::unique_ptr<PasswordForm>> forms;
   PasswordStoreChangeList changes;
   if (!login_metadata_db_ ||
       !login_metadata_db_->GetAutoSignInLogins(&forms)) {
@@ -1215,7 +1180,7 @@
   }
 
   std::set<GURL> origins_to_update;
-  for (const auto* form : forms) {
+  for (const auto& form : forms) {
     if (origin_filter.Run(form->origin))
       origins_to_update.insert(form->origin);
   }
@@ -1226,7 +1191,7 @@
       origins_updated.insert(origin);
   }
 
-  for (const auto* form : forms) {
+  for (const auto& form : forms) {
     if (origins_updated.count(form->origin)) {
       changes.push_back(
           PasswordStoreChange(PasswordStoreChange::UPDATE, *form));
@@ -1250,21 +1215,16 @@
   chrome::ScopedSecKeychainSetUserInteractionAllowed user_interaction_allowed(
       false);
 
-  // TODO(crbug.com/555132): "new_format" means std::vector instead of
-  // ScopedVector. Remove |database_forms_new_format| in favour of
-  // |database_forms| as soon as the latter is migrated to std::vector.
-  std::vector<std::unique_ptr<PasswordForm>> database_forms_new_format;
+  std::vector<std::unique_ptr<PasswordForm>> database_forms;
   if (!login_metadata_db_ ||
-      !login_metadata_db_->GetLogins(form, &database_forms_new_format)) {
+      !login_metadata_db_->GetLogins(form, &database_forms)) {
     return std::vector<std::unique_ptr<PasswordForm>>();
   }
-  ScopedVector<PasswordForm> database_forms =
-      ConvertToScopedVector(std::move(database_forms_new_format));
 
   // Let's gather all signon realms we want to match with keychain entries.
   std::set<std::string> realm_set;
   realm_set.insert(form.signon_realm);
-  for (const autofill::PasswordForm* db_form : database_forms) {
+  for (const std::unique_ptr<PasswordForm>& db_form : database_forms) {
     // TODO(vabr): We should not be getting different schemes here.
     // http://crbug.com/340112
     if (form.scheme != db_form->scheme)
@@ -1272,32 +1232,32 @@
     if (db_form->is_public_suffix_match || db_form->is_affiliation_based_match)
       realm_set.insert(db_form->signon_realm);
   }
-  ScopedVector<autofill::PasswordForm> keychain_forms;
+  std::vector<std::unique_ptr<PasswordForm>> keychain_forms;
   for (std::set<std::string>::const_iterator realm = realm_set.begin();
        realm != realm_set.end(); ++realm) {
     MacKeychainPasswordFormAdapter keychain_adapter(keychain_.get());
-    ScopedVector<autofill::PasswordForm> temp_keychain_forms =
+    std::vector<std::unique_ptr<PasswordForm>> temp_keychain_forms =
         keychain_adapter.PasswordsFillingForm(*realm, form.scheme);
     AppendSecondToFirst(&keychain_forms, &temp_keychain_forms);
   }
 
-  ScopedVector<autofill::PasswordForm> matched_forms;
+  std::vector<std::unique_ptr<PasswordForm>> matched_forms;
   internal_keychain_helpers::MergePasswordForms(
       &keychain_forms, &database_forms, &matched_forms);
 
   // Strip any blacklist entries out of the unused Keychain array, then take
   // all the entries that are left (which we can use as imported passwords).
-  ScopedVector<PasswordForm> keychain_blacklist_forms;
+  std::vector<std::unique_ptr<PasswordForm>> keychain_blacklist_forms;
   internal_keychain_helpers::ExtractNonKeychainForms(&keychain_forms,
                                                      &keychain_blacklist_forms);
   AppendSecondToFirst(&matched_forms, &keychain_forms);
 
   if (!database_forms.empty()) {
     RemoveDatabaseForms(&database_forms);
-    NotifyLoginsChanged(FormsToRemoveChangeList(database_forms.get()));
+    NotifyLoginsChanged(FormsToRemoveChangeList(database_forms));
   }
 
-  return password_manager_util::ConvertScopedVector(std::move(matched_forms));
+  return matched_forms;
 }
 
 bool PasswordStoreMac::FillAutofillableLogins(
@@ -1305,22 +1265,17 @@
   DCHECK(GetBackgroundTaskRunner()->BelongsToCurrentThread());
   forms->clear();
 
-  std::vector<std::unique_ptr<PasswordForm>> database_forms_new_format;
+  std::vector<std::unique_ptr<PasswordForm>> database_forms;
   if (!login_metadata_db_ ||
-      !login_metadata_db_->GetAutofillableLogins(&database_forms_new_format))
+      !login_metadata_db_->GetAutofillableLogins(&database_forms))
     return false;
-  ScopedVector<PasswordForm> database_forms =
-      ConvertToScopedVector(std::move(database_forms_new_format));
 
-  ScopedVector<PasswordForm> forms_scopedvector;
   internal_keychain_helpers::GetPasswordsForForms(*keychain_, &database_forms,
-                                                  &forms_scopedvector);
-  *forms =
-      password_manager_util::ConvertScopedVector(std::move(forms_scopedvector));
+                                                  forms);
 
   if (!database_forms.empty()) {
     RemoveDatabaseForms(&database_forms);
-    NotifyLoginsChanged(FormsToRemoveChangeList(database_forms.get()));
+    NotifyLoginsChanged(FormsToRemoveChangeList(database_forms));
   }
 
   return true;
@@ -1361,7 +1316,7 @@
 }
 
 bool PasswordStoreMac::DatabaseHasFormMatchingKeychainForm(
-    const autofill::PasswordForm& form) {
+    const PasswordForm& form) {
   DCHECK(login_metadata_db_);
   bool has_match = false;
   std::vector<std::unique_ptr<PasswordForm>> database_forms;
@@ -1383,40 +1338,36 @@
 }
 
 void PasswordStoreMac::RemoveDatabaseForms(
-  ScopedVector<autofill::PasswordForm>* forms) {
+    std::vector<std::unique_ptr<PasswordForm>>* forms) {
   DCHECK(login_metadata_db_);
-  ScopedVector<autofill::PasswordForm> removed_forms;
-  MoveAllFormsOut(forms, [this, &removed_forms](
-                             std::unique_ptr<autofill::PasswordForm> form) {
+  std::vector<std::unique_ptr<PasswordForm>> removed_forms;
+  for (std::unique_ptr<PasswordForm>& form : *forms) {
     if (login_metadata_db_->RemoveLogin(*form))
       removed_forms.push_back(std::move(form));
-  });
+  }
   removed_forms.swap(*forms);
 }
 
 void PasswordStoreMac::RemoveKeychainForms(
-    const std::vector<PasswordForm*>& forms) {
+    const std::vector<std::unique_ptr<PasswordForm>>& forms) {
   MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_.get());
   owned_keychain_adapter.SetFindsOnlyOwnedItems(true);
-  for (std::vector<PasswordForm*>::const_iterator i = forms.begin();
-       i != forms.end(); ++i) {
-    owned_keychain_adapter.RemovePassword(**i);
+  for (const auto& form : forms) {
+    owned_keychain_adapter.RemovePassword(*form);
   }
 }
 
 void PasswordStoreMac::CleanOrphanedForms(
-    ScopedVector<autofill::PasswordForm>* orphaned_forms) {
+    std::vector<std::unique_ptr<PasswordForm>>* orphaned_forms) {
   DCHECK(orphaned_forms);
   DCHECK(login_metadata_db_);
 
-  std::vector<std::unique_ptr<PasswordForm>> database_forms_new_format;
-  if (!login_metadata_db_->GetAutofillableLogins(&database_forms_new_format))
+  std::vector<std::unique_ptr<PasswordForm>> database_forms;
+  if (!login_metadata_db_->GetAutofillableLogins(&database_forms))
     return;
-  ScopedVector<PasswordForm> database_forms =
-      ConvertToScopedVector(std::move(database_forms_new_format));
 
   // Filter forms with corresponding Keychain entry out of |database_forms|.
-  ScopedVector<PasswordForm> forms_with_keychain_entry;
+  std::vector<std::unique_ptr<PasswordForm>> forms_with_keychain_entry;
   internal_keychain_helpers::GetPasswordsForForms(*keychain_, &database_forms,
                                                   &forms_with_keychain_entry);
 
diff --git a/chrome/browser/password_manager/password_store_mac.h b/chrome/browser/password_manager/password_store_mac.h
index b7a58150..7389a3b 100644
--- a/chrome/browser/password_manager/password_store_mac.h
+++ b/chrome/browser/password_manager/password_store_mac.h
@@ -11,7 +11,6 @@
 
 #include "base/callback_forward.h"
 #include "base/macros.h"
-#include "base/memory/scoped_vector.h"
 #include "base/threading/thread.h"
 #include "components/password_manager/core/browser/login_database.h"
 #include "components/password_manager/core/browser/password_store.h"
@@ -128,16 +127,18 @@
 
   // Removes the given forms from the database. After the call |forms| contains
   // only those forms which were successfully removed.
-  void RemoveDatabaseForms(ScopedVector<autofill::PasswordForm>* forms);
+  void RemoveDatabaseForms(
+      std::vector<std::unique_ptr<autofill::PasswordForm>>* forms);
 
   // Removes the given forms from the Keychain.
   void RemoveKeychainForms(
-      const std::vector<autofill::PasswordForm*>& forms);
+      const std::vector<std::unique_ptr<autofill::PasswordForm>>& forms);
 
   // Searches the database for forms without a corresponding entry in the
   // keychain. Removes those forms from the database, and adds them to
   // |orphaned_forms|.
-  void CleanOrphanedForms(ScopedVector<autofill::PasswordForm>* orphaned_forms);
+  void CleanOrphanedForms(
+      std::vector<std::unique_ptr<autofill::PasswordForm>>* orphaned_forms);
 
   std::unique_ptr<crypto::AppleKeychain> keychain_;
 
diff --git a/chrome/browser/password_manager/password_store_mac_internal.h b/chrome/browser/password_manager/password_store_mac_internal.h
index e45742a..5c9fc87 100644
--- a/chrome/browser/password_manager/password_store_mac_internal.h
+++ b/chrome/browser/password_manager/password_store_mac_internal.h
@@ -11,7 +11,6 @@
 #include <vector>
 
 #include "base/macros.h"
-#include "base/memory/scoped_vector.h"
 #include "components/autofill/core/common/password_form.h"
 #include "crypto/apple_keychain.h"
 
@@ -27,7 +26,7 @@
   explicit MacKeychainPasswordFormAdapter(const AppleKeychain* keychain);
 
   // Returns all keychain entries matching |signon_realm| and |scheme|.
-  ScopedVector<autofill::PasswordForm> PasswordsFillingForm(
+  std::vector<std::unique_ptr<autofill::PasswordForm>> PasswordsFillingForm(
       const std::string& signon_realm,
       autofill::PasswordForm::Scheme scheme);
 
@@ -48,7 +47,8 @@
 
   // Returns all keychain entries corresponding to password forms.
   // TODO(vabr): This is only used in tests, should be moved there.
-  ScopedVector<autofill::PasswordForm> GetAllPasswordFormPasswords();
+  std::vector<std::unique_ptr<autofill::PasswordForm>>
+  GetAllPasswordFormPasswords();
 
   // Creates a new keychain entry from |form|, or updates the password of an
   // existing keychain entry if there is a collision. Returns true if a keychain
@@ -66,8 +66,8 @@
  private:
   // Returns PasswordForm instances transformed from |items|. Also calls
   // AppleKeychain::Free on all of the keychain items and clears |items|.
-  ScopedVector<autofill::PasswordForm> ConvertKeychainItemsToForms(
-      std::vector<SecKeychainItemRef>* items);
+  std::vector<std::unique_ptr<autofill::PasswordForm>>
+  ConvertKeychainItemsToForms(std::vector<SecKeychainItemRef>* items);
 
   // Searches |keychain| for the specific keychain entry that corresponds to the
   // given form, and returns it (or NULL if no match is found). The caller is
@@ -171,16 +171,18 @@
 // password can be found (and which aren't blacklist entries), and for
 // keychain_forms its entries that weren't merged into at least one database
 // form.
-void MergePasswordForms(ScopedVector<autofill::PasswordForm>* keychain_forms,
-                        ScopedVector<autofill::PasswordForm>* database_forms,
-                        ScopedVector<autofill::PasswordForm>* merged_forms);
+void MergePasswordForms(
+    std::vector<std::unique_ptr<autofill::PasswordForm>>* keychain_forms,
+    std::vector<std::unique_ptr<autofill::PasswordForm>>* database_forms,
+    std::vector<std::unique_ptr<autofill::PasswordForm>>* merged_forms);
 
 // For every form in |database_forms|, if such a form has a corresponding entry
 // in |keychain|, this adds the password from the entry and moves that form from
 // |database_forms| into |passwords|.
-void GetPasswordsForForms(const AppleKeychain& keychain,
-                          ScopedVector<autofill::PasswordForm>* database_forms,
-                          ScopedVector<autofill::PasswordForm>* passwords);
+void GetPasswordsForForms(
+    const AppleKeychain& keychain,
+    std::vector<std::unique_ptr<autofill::PasswordForm>>* database_forms,
+    std::vector<std::unique_ptr<autofill::PasswordForm>>* passwords);
 
 // Loads all items in the system keychain into |keychain_items|, creates for
 // each keychain item a corresponding PasswordForm that doesn't contain any
@@ -213,7 +215,8 @@
 
 // Returns PasswordForm instances populated with password data for each keychain
 // entry in |item_form_pairs| that could be merged with |query_form|.
-ScopedVector<autofill::PasswordForm> ExtractPasswordsMergeableWithForm(
+std::vector<std::unique_ptr<autofill::PasswordForm>>
+ExtractPasswordsMergeableWithForm(
     const AppleKeychain& keychain,
     const std::vector<ItemFormPair>& item_form_pairs,
     const autofill::PasswordForm& query_form);
diff --git a/chrome/browser/password_manager/password_store_mac_unittest.cc b/chrome/browser/password_manager/password_store_mac_unittest.cc
index 96ae6b84..e0f6a98 100644
--- a/chrome/browser/password_manager/password_store_mac_unittest.cc
+++ b/chrome/browser/password_manager/password_store_mac_unittest.cc
@@ -116,7 +116,7 @@
 // TODO(stuartmorgan): This is current order-dependent; ideally it shouldn't
 // matter if |forms| and |expectations| are scrambled.
 void CheckFormsAgainstExpectations(
-    const std::vector<PasswordForm*>& forms,
+    const std::vector<std::unique_ptr<PasswordForm>>& forms,
     const std::vector<PasswordFormData*>& expectations,
 
     const char* forms_label,
@@ -129,7 +129,7 @@
   for (unsigned int i = 0; i < expectations.size(); ++i) {
     SCOPED_TRACE(testing::Message() << forms_label << " in test " << test_number
                                     << ", item " << i);
-    PasswordForm* form = forms[i];
+    PasswordForm* form = forms[i].get();
     PasswordFormData* expectation = expectations[i];
     EXPECT_EQ(expectation->scheme, form->scheme);
     EXPECT_EQ(std::string(expectation->signon_realm), form->signon_realm);
@@ -497,7 +497,7 @@
         CreatePasswordFormFromDataForTesting(test_data[i].data);
 
     // Check matches treating the form as a fill target.
-    ScopedVector<autofill::PasswordForm> matching_items =
+    std::vector<std::unique_ptr<PasswordForm>> matching_items =
         keychain_adapter.PasswordsFillingForm(query_form->signon_realm,
                                               query_form->scheme);
     EXPECT_EQ(test_data[i].expected_fill_matches, matching_items.size());
@@ -577,27 +577,27 @@
 
     // Make sure that the matching isn't looser than it should be by checking
     // that slightly altered forms don't match.
-    ScopedVector<autofill::PasswordForm> modified_forms;
+    std::vector<std::unique_ptr<PasswordForm>> modified_forms;
 
-    modified_forms.push_back(new PasswordForm(*base_form));
+    modified_forms.push_back(base::MakeUnique<PasswordForm>(*base_form));
     modified_forms.back()->username_value = ASCIIToUTF16("wrong_user");
 
-    modified_forms.push_back(new PasswordForm(*base_form));
-    SetPasswordFormPath(modified_forms.back(), "elsewhere.html");
+    modified_forms.push_back(base::MakeUnique<PasswordForm>(*base_form));
+    SetPasswordFormPath(modified_forms.back().get(), "elsewhere.html");
 
-    modified_forms.push_back(new PasswordForm(*base_form));
+    modified_forms.push_back(base::MakeUnique<PasswordForm>(*base_form));
     modified_forms.back()->scheme = PasswordForm::SCHEME_OTHER;
 
-    modified_forms.push_back(new PasswordForm(*base_form));
-    SetPasswordFormPort(modified_forms.back(), "1234");
+    modified_forms.push_back(base::MakeUnique<PasswordForm>(*base_form));
+    SetPasswordFormPort(modified_forms.back().get(), "1234");
 
-    modified_forms.push_back(new PasswordForm(*base_form));
+    modified_forms.push_back(base::MakeUnique<PasswordForm>(*base_form));
     modified_forms.back()->blacklisted_by_user = true;
 
     if (base_form->scheme == PasswordForm::SCHEME_BASIC ||
         base_form->scheme == PasswordForm::SCHEME_DIGEST) {
-      modified_forms.push_back(new PasswordForm(*base_form));
-      SetPasswordFormRealm(modified_forms.back(), "incorrect");
+      modified_forms.push_back(base::MakeUnique<PasswordForm>(*base_form));
+      SetPasswordFormRealm(modified_forms.back().get(), "incorrect");
     }
 
     for (unsigned int j = 0; j < modified_forms.size(); ++j) {
@@ -1070,31 +1070,28 @@
   test_data[MERGE_OUTPUT][current_test].push_back(&merged_android);
 
   for (unsigned int test_case = 0; test_case <= current_test; ++test_case) {
-    ScopedVector<autofill::PasswordForm> keychain_forms;
+    std::vector<std::unique_ptr<PasswordForm>> keychain_forms;
     for (std::vector<PasswordFormData*>::iterator i =
              test_data[KEYCHAIN_INPUT][test_case].begin();
          i != test_data[KEYCHAIN_INPUT][test_case].end(); ++i) {
-      keychain_forms.push_back(
-          CreatePasswordFormFromDataForTesting(*(*i)).release());
+      keychain_forms.push_back(CreatePasswordFormFromDataForTesting(*(*i)));
     }
-    ScopedVector<autofill::PasswordForm> database_forms;
+    std::vector<std::unique_ptr<PasswordForm>> database_forms;
     for (std::vector<PasswordFormData*>::iterator i =
              test_data[DATABASE_INPUT][test_case].begin();
          i != test_data[DATABASE_INPUT][test_case].end(); ++i) {
-      database_forms.push_back(
-          CreatePasswordFormFromDataForTesting(*(*i)).release());
+      database_forms.push_back(CreatePasswordFormFromDataForTesting(*(*i)));
     }
 
-    ScopedVector<autofill::PasswordForm> merged_forms;
+    std::vector<std::unique_ptr<PasswordForm>> merged_forms;
     internal_keychain_helpers::MergePasswordForms(
         &keychain_forms, &database_forms, &merged_forms);
 
-    CHECK_FORMS(keychain_forms.get(), test_data[KEYCHAIN_OUTPUT][test_case],
+    CHECK_FORMS(keychain_forms, test_data[KEYCHAIN_OUTPUT][test_case],
                 test_case);
-    CHECK_FORMS(database_forms.get(), test_data[DATABASE_OUTPUT][test_case],
+    CHECK_FORMS(database_forms, test_data[DATABASE_OUTPUT][test_case],
                 test_case);
-    CHECK_FORMS(merged_forms.get(), test_data[MERGE_OUTPUT][test_case],
-                test_case);
+    CHECK_FORMS(merged_forms, test_data[MERGE_OUTPUT][test_case], test_case);
   }
 }
 
@@ -1118,12 +1115,11 @@
        "http://some.domain.com/path.html", "http://some.domain.com/action.cgi",
        L"submit", L"username", L"password", NULL, NULL, true, 1212121212},
   };
-  ScopedVector<autofill::PasswordForm> database_forms;
-  for (unsigned int i = 0; i < arraysize(db_data); ++i) {
-    database_forms.push_back(
-        CreatePasswordFormFromDataForTesting(db_data[i]).release());
+  std::vector<std::unique_ptr<PasswordForm>> database_forms;
+  for (const PasswordFormData& form_data : db_data) {
+    database_forms.push_back(CreatePasswordFormFromDataForTesting(form_data));
   }
-  ScopedVector<autofill::PasswordForm> merged_forms;
+  std::vector<std::unique_ptr<PasswordForm>> merged_forms;
   internal_keychain_helpers::GetPasswordsForForms(*keychain_, &database_forms,
                                                   &merged_forms);
   EXPECT_EQ(2U, database_forms.size());
@@ -1145,12 +1141,11 @@
        L"username", L"password", L"joe_user", L"non_empty_password", true,
        1240000000},
   };
-  ScopedVector<autofill::PasswordForm> database_forms;
-  for (unsigned int i = 0; i < arraysize(db_data); ++i) {
-    database_forms.push_back(
-        CreatePasswordFormFromDataForTesting(db_data[i]).release());
+  std::vector<std::unique_ptr<PasswordForm>> database_forms;
+  for (const PasswordFormData& form_data : db_data) {
+    database_forms.push_back(CreatePasswordFormFromDataForTesting(form_data));
   }
-  ScopedVector<autofill::PasswordForm> merged_forms;
+  std::vector<std::unique_ptr<PasswordForm>> merged_forms;
   internal_keychain_helpers::GetPasswordsForForms(*keychain_, &database_forms,
                                                   &merged_forms);
   EXPECT_EQ(2U, database_forms.size());
@@ -1243,11 +1238,11 @@
     owned_keychain_adapter.AddPassword(*form);
   }
 
-  ScopedVector<autofill::PasswordForm> all_passwords =
+  std::vector<std::unique_ptr<PasswordForm>> all_passwords =
       keychain_adapter.GetAllPasswordFormPasswords();
   EXPECT_EQ(9 + arraysize(owned_password_data), all_passwords.size());
 
-  ScopedVector<autofill::PasswordForm> owned_passwords =
+  std::vector<std::unique_ptr<PasswordForm>> owned_passwords =
       owned_keychain_adapter.GetAllPasswordFormPasswords();
   EXPECT_EQ(arraysize(owned_password_data), owned_passwords.size());
 }
@@ -1491,7 +1486,7 @@
     std::unique_ptr<PasswordForm> query_form =
         CreatePasswordFormFromDataForTesting(updates[i].form_data);
 
-    ScopedVector<autofill::PasswordForm> matching_items =
+    std::vector<std::unique_ptr<PasswordForm>> matching_items =
         keychain_adapter.PasswordsFillingForm(query_form->signon_realm,
                                               query_form->scheme);
     if (updates[i].password) {
@@ -1571,7 +1566,7 @@
   FinishAsyncProcessing();
 
   // No trace of www.facebook.com.
-  ScopedVector<autofill::PasswordForm> matching_items =
+  std::vector<std::unique_ptr<PasswordForm>> matching_items =
       owned_keychain_adapter.PasswordsFillingForm(www_form->signon_realm,
                                                   www_form->scheme);
   EXPECT_EQ(0u, matching_items.size());
@@ -1690,7 +1685,7 @@
   // Check the keychain content.
   MacKeychainPasswordFormAdapter owned_keychain_adapter(test->keychain());
   owned_keychain_adapter.SetFindsOnlyOwnedItems(false);
-  ScopedVector<PasswordForm> matching_items(
+  std::vector<std::unique_ptr<PasswordForm>> matching_items(
       owned_keychain_adapter.PasswordsFillingForm(form_facebook->signon_realm,
                                                   form_facebook->scheme));
   EXPECT_EQ(1u, matching_items.size());
@@ -1791,7 +1786,7 @@
   EXPECT_CALL(observer, OnLoginsChanged(GetAddChangeList(*form_google)));
   observer.WaitAndVerify(this);
 
-  ScopedVector<autofill::PasswordForm> forms;
+  std::vector<std::unique_ptr<PasswordForm>> forms;
   EXPECT_TRUE(login_db()->GetAutoSignInLogins(&forms));
   EXPECT_EQ(2u, forms.size());
   EXPECT_FALSE(forms[0]->skip_zero_click);
@@ -1876,7 +1871,7 @@
   EXPECT_EQ(0u, matching_items.size());
 
   // Check the first facebook form is still there.
-  ScopedVector<PasswordForm> matching_keychain_items;
+  std::vector<std::unique_ptr<PasswordForm>> matching_keychain_items;
   matching_keychain_items = owned_keychain_adapter.PasswordsFillingForm(
       www_form->signon_realm, www_form->scheme);
   ASSERT_EQ(1u, matching_keychain_items.size());
@@ -2104,15 +2099,13 @@
       "http://web.site.com/path/to/page.html", NULL, NULL, NULL, NULL,
       L"anonymous", L"knock-knock", false, 0 };
   keychain_adapter.AddPassword(*CreatePasswordFormFromDataForTesting(data2));
-  std::vector<std::unique_ptr<autofill::PasswordForm>> passwords =
-      password_manager_util::ConvertScopedVector(
-          keychain_adapter.GetAllPasswordFormPasswords());
+  std::vector<std::unique_ptr<PasswordForm>> passwords =
+      keychain_adapter.GetAllPasswordFormPasswords();
   EXPECT_EQ(2u, passwords.size());
 
   // Delete everyhting but only the Chrome-owned item should be affected.
   PasswordStoreMac::CleanUpKeychain(keychain(), passwords);
-  passwords = password_manager_util::ConvertScopedVector(
-      keychain_adapter.GetAllPasswordFormPasswords());
+  passwords = keychain_adapter.GetAllPasswordFormPasswords();
   ASSERT_EQ(1u, passwords.size());
   EXPECT_EQ("http://some.domain.com/", passwords[0]->signon_realm);
   EXPECT_EQ(ASCIIToUTF16("sekrit"), passwords[0]->password_value);
diff --git a/chrome/browser/password_manager/password_store_x.cc b/chrome/browser/password_manager/password_store_x.cc
index 2b0b4bc..513a25f9 100644
--- a/chrome/browser/password_manager/password_store_x.cc
+++ b/chrome/browser/password_manager/password_store_x.cc
@@ -44,11 +44,11 @@
     base::Time delete_begin,
     base::Time delete_end,
     PasswordStoreChangeList* changes) {
-  ScopedVector<autofill::PasswordForm> forms;
+  std::vector<std::unique_ptr<PasswordForm>> forms;
   if (!backend->GetAllLogins(&forms))
     return false;
 
-  for (const autofill::PasswordForm* form : forms) {
+  for (const auto& form : forms) {
     if (url_filter.Run(form->origin) && form->date_created >= delete_begin &&
         (delete_end.is_null() || form->date_created < delete_end) &&
         !backend->RemoveLogin(*form, changes))
@@ -192,12 +192,8 @@
 std::vector<std::unique_ptr<PasswordForm>> PasswordStoreX::FillMatchingLogins(
     const FormDigest& form) {
   CheckMigration();
-  ScopedVector<autofill::PasswordForm> matched_forms_scopedvector;
-  if (use_native_backend() &&
-      backend_->GetLogins(form, &matched_forms_scopedvector)) {
-    std::vector<std::unique_ptr<PasswordForm>> matched_forms =
-        password_manager_util::ConvertScopedVector(
-            std::move(matched_forms_scopedvector));
+  std::vector<std::unique_ptr<PasswordForm>> matched_forms;
+  if (use_native_backend() && backend_->GetLogins(form, &matched_forms)) {
     SortLoginsByOrigin(&matched_forms);
     // The native backend may succeed and return no data even while locked, if
     // the query did not match anything stored. So we continue to allow fallback
@@ -214,11 +210,7 @@
 bool PasswordStoreX::FillAutofillableLogins(
     std::vector<std::unique_ptr<PasswordForm>>* forms) {
   CheckMigration();
-  ScopedVector<autofill::PasswordForm> forms_scopedvector;
-  if (use_native_backend() &&
-      backend_->GetAutofillableLogins(&forms_scopedvector)) {
-    *forms = password_manager_util::ConvertScopedVector(
-        std::move(forms_scopedvector));
+  if (use_native_backend() && backend_->GetAutofillableLogins(forms)) {
     SortLoginsByOrigin(forms);
     // See GetLoginsImpl() for why we disallow fallback conditionally here.
     if (!forms->empty())
@@ -233,11 +225,7 @@
 bool PasswordStoreX::FillBlacklistLogins(
     std::vector<std::unique_ptr<PasswordForm>>* forms) {
   CheckMigration();
-  ScopedVector<autofill::PasswordForm> forms_scopedvector;
-  if (use_native_backend() &&
-      backend_->GetBlacklistLogins(&forms_scopedvector)) {
-    *forms = password_manager_util::ConvertScopedVector(
-        std::move(forms_scopedvector));
+  if (use_native_backend() && backend_->GetBlacklistLogins(forms)) {
     // See GetLoginsImpl() for why we disallow fallback conditionally here.
     SortLoginsByOrigin(forms);
     if (!forms->empty())
diff --git a/chrome/browser/password_manager/password_store_x.h b/chrome/browser/password_manager/password_store_x.h
index 82a811b..ec314d1 100644
--- a/chrome/browser/password_manager/password_store_x.h
+++ b/chrome/browser/password_manager/password_store_x.h
@@ -11,7 +11,6 @@
 #include <vector>
 
 #include "base/macros.h"
-#include "base/memory/scoped_vector.h"
 #include "base/time/time.h"
 #include "components/password_manager/core/browser/password_store_default.h"
 
@@ -73,13 +72,16 @@
     // matching |form|, all stored non-blacklisted credentials, and all stored
     // blacklisted credentials, respectively. On success, they return true.
     virtual bool GetLogins(const FormDigest& form,
-                           ScopedVector<autofill::PasswordForm>* forms)
-        WARN_UNUSED_RESULT = 0;
+                           std::vector<std::unique_ptr<autofill::PasswordForm>>*
+                               forms) WARN_UNUSED_RESULT = 0;
     virtual bool GetAutofillableLogins(
-        ScopedVector<autofill::PasswordForm>* forms) WARN_UNUSED_RESULT = 0;
-    virtual bool GetBlacklistLogins(ScopedVector<autofill::PasswordForm>* forms)
+        std::vector<std::unique_ptr<autofill::PasswordForm>>* forms)
         WARN_UNUSED_RESULT = 0;
-    virtual bool GetAllLogins(ScopedVector<autofill::PasswordForm>* forms)
+    virtual bool GetBlacklistLogins(
+        std::vector<std::unique_ptr<autofill::PasswordForm>>* forms)
+        WARN_UNUSED_RESULT = 0;
+    virtual bool GetAllLogins(
+        std::vector<std::unique_ptr<autofill::PasswordForm>>* forms)
         WARN_UNUSED_RESULT = 0;
   };
 
diff --git a/chrome/browser/password_manager/password_store_x_unittest.cc b/chrome/browser/password_manager/password_store_x_unittest.cc
index 06206fb..bb4c518 100644
--- a/chrome/browser/password_manager/password_store_x_unittest.cc
+++ b/chrome/browser/password_manager/password_store_x_unittest.cc
@@ -92,8 +92,8 @@
 
   // Use this as a landmine to check whether results of failed Get*Logins calls
   // get ignored.
-  static ScopedVector<autofill::PasswordForm> CreateTrashForms() {
-    ScopedVector<autofill::PasswordForm> forms;
+  static std::vector<std::unique_ptr<PasswordForm>> CreateTrashForms() {
+    std::vector<std::unique_ptr<PasswordForm>> forms;
     PasswordForm trash;
     trash.username_element = base::ASCIIToUTF16("trash u. element");
     trash.username_value = base::ASCIIToUTF16("trash u. value");
@@ -101,30 +101,31 @@
     trash.password_value = base::ASCIIToUTF16("trash p. value");
     for (size_t i = 0; i < 3; ++i) {
       trash.origin = GURL(base::StringPrintf("http://trash%zu.com", i));
-      forms.push_back(new PasswordForm(trash));
+      forms.push_back(base::MakeUnique<PasswordForm>(trash));
     }
     return forms;
   }
 
   bool GetLogins(const PasswordStore::FormDigest& form,
-                 ScopedVector<autofill::PasswordForm>* forms) override {
+                 std::vector<std::unique_ptr<PasswordForm>>* forms) override {
     *forms = CreateTrashForms();
     return false;
   }
 
   bool GetAutofillableLogins(
-      ScopedVector<autofill::PasswordForm>* forms) override {
+      std::vector<std::unique_ptr<PasswordForm>>* forms) override {
     *forms = CreateTrashForms();
     return false;
   }
 
   bool GetBlacklistLogins(
-      ScopedVector<autofill::PasswordForm>* forms) override {
+      std::vector<std::unique_ptr<PasswordForm>>* forms) override {
     *forms = CreateTrashForms();
     return false;
   }
 
-  bool GetAllLogins(ScopedVector<autofill::PasswordForm>* forms) override {
+  bool GetAllLogins(
+      std::vector<std::unique_ptr<PasswordForm>>* forms) override {
     *forms = CreateTrashForms();
     return false;
   }
@@ -199,32 +200,33 @@
   }
 
   bool GetLogins(const PasswordStore::FormDigest& form,
-                 ScopedVector<autofill::PasswordForm>* forms) override {
+                 std::vector<std::unique_ptr<PasswordForm>>* forms) override {
     for (size_t i = 0; i < all_forms_.size(); ++i)
       if (all_forms_[i].signon_realm == form.signon_realm)
-        forms->push_back(new PasswordForm(all_forms_[i]));
+        forms->push_back(base::MakeUnique<PasswordForm>(all_forms_[i]));
     return true;
   }
 
   bool GetAutofillableLogins(
-      ScopedVector<autofill::PasswordForm>* forms) override {
+      std::vector<std::unique_ptr<PasswordForm>>* forms) override {
     for (size_t i = 0; i < all_forms_.size(); ++i)
       if (!all_forms_[i].blacklisted_by_user)
-        forms->push_back(new PasswordForm(all_forms_[i]));
+        forms->push_back(base::MakeUnique<PasswordForm>(all_forms_[i]));
     return true;
   }
 
   bool GetBlacklistLogins(
-      ScopedVector<autofill::PasswordForm>* forms) override {
+      std::vector<std::unique_ptr<PasswordForm>>* forms) override {
     for (size_t i = 0; i < all_forms_.size(); ++i)
       if (all_forms_[i].blacklisted_by_user)
-        forms->push_back(new PasswordForm(all_forms_[i]));
+        forms->push_back(base::MakeUnique<PasswordForm>(all_forms_[i]));
     return true;
   }
 
-  bool GetAllLogins(ScopedVector<autofill::PasswordForm>* forms) override {
+  bool GetAllLogins(
+      std::vector<std::unique_ptr<PasswordForm>>* forms) override {
     for (size_t i = 0; i < all_forms_.size(); ++i)
-      forms->push_back(new PasswordForm(all_forms_[i]));
+      forms->push_back(base::MakeUnique<PasswordForm>(all_forms_[i]));
     return true;
   }
 
diff --git a/chrome/browser/predictors/resource_prefetch_predictor_browsertest.cc b/chrome/browser/predictors/resource_prefetch_predictor_browsertest.cc
index 3016a1e..c9ab1bf 100644
--- a/chrome/browser/predictors/resource_prefetch_predictor_browsertest.cc
+++ b/chrome/browser/predictors/resource_prefetch_predictor_browsertest.cc
@@ -468,9 +468,8 @@
   NavigateToURLAndCheckSubresources(GetURL(kHtmlDocumentWritePath));
 }
 
-// Disabled due to flakiness (crbug.com/673028).
 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest,
-                       DISABLED_LearningJavascriptAppendChild) {
+                       LearningJavascriptAppendChild) {
   auto externalScript =
       AddExternalResource(GetURL(kScriptAppendChildPath),
                           content::RESOURCE_TYPE_SCRIPT, net::MEDIUM);
diff --git a/chrome/browser/prerender/prerender_handle.cc b/chrome/browser/prerender/prerender_handle.cc
index f15a148..8c51ff7 100644
--- a/chrome/browser/prerender/prerender_handle.cc
+++ b/chrome/browser/prerender/prerender_handle.cc
@@ -67,14 +67,6 @@
   return prerender_data_ ? prerender_data_->contents() : nullptr;
 }
 
-bool PrerenderHandle::Matches(
-    const GURL& url,
-    const content::SessionStorageNamespace* session_storage_namespace) const {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  return prerender_data_ &&
-         prerender_data_->contents()->Matches(url, session_storage_namespace);
-}
-
 PrerenderHandle::PrerenderHandle(
     PrerenderManager::PrerenderData* prerender_data)
     : observer_(nullptr), weak_ptr_factory_(this) {
diff --git a/chrome/browser/prerender/prerender_handle.h b/chrome/browser/prerender/prerender_handle.h
index 168af0c..9beac51 100644
--- a/chrome/browser/prerender/prerender_handle.h
+++ b/chrome/browser/prerender/prerender_handle.h
@@ -11,12 +11,6 @@
 #include "base/memory/weak_ptr.h"
 #include "chrome/browser/prerender/prerender_manager.h"
 
-class GURL;
-
-namespace content {
-class SessionStorageNamespace;
-}
-
 namespace prerender {
 
 class PrerenderContents;
@@ -77,11 +71,6 @@
 
   PrerenderContents* contents() const;
 
-  // Returns whether the prerender matches the URL provided.
-  bool Matches(
-      const GURL& url,
-      const content::SessionStorageNamespace* session_storage_namespace) const;
-
   // Returns whether this PrerenderHandle represents the same prerender as
   // the other PrerenderHandle object specified.
   bool RepresentingSamePrerenderAs(PrerenderHandle* other) const;
diff --git a/chrome/browser/resources/md_extensions/sidebar.html b/chrome/browser/resources/md_extensions/sidebar.html
index 5a4e6bc..fb96c60 100644
--- a/chrome/browser/resources/md_extensions/sidebar.html
+++ b/chrome/browser/resources/md_extensions/sidebar.html
@@ -5,6 +5,7 @@
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-checkbox/paper-checkbox.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-item/paper-item.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-menu/paper-menu.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html">
 <link rel="import" href="chrome://extensions/icons.html">
 
 <dom-module id="extensions-sidebar">
@@ -24,7 +25,7 @@
         --paper-menu-background-color: transparent;
         --paper-menu-selected-item: {
           background-color: transparent;
-          color: rgb(66, 133, 244);
+          color: var(--google-blue-700);
           font-weight: normal;
         }
 
@@ -49,8 +50,8 @@
       }
 
       #developer-mode-checkbox {
-        --paper-checkbox-checked-color: rgb(66, 133, 244);
-        --primary-text-color: #5A5A5A;
+        --paper-checkbox-checked-color: var(--google-blue-700);
+        --primary-text-color: #5a5a5a;
       }
 
       #developer-mode {
diff --git a/chrome/browser/resources/settings/settings_menu/settings_menu.html b/chrome/browser/resources/settings/settings_menu/settings_menu.html
index c53e02b..ab0864f8 100644
--- a/chrome/browser/resources/settings/settings_menu/settings_menu.html
+++ b/chrome/browser/resources/settings/settings_menu/settings_menu.html
@@ -13,7 +13,7 @@
   <template>
     <style include="settings-shared">
       #about-menu[about-selected] {
-        color: var(--google-blue-500);
+        color: var(--google-blue-700);
       }
 
       iron-icon {
@@ -22,7 +22,7 @@
       }
 
       .iron-selected:not(.menu-trigger) > iron-icon {
-        fill: var(--google-blue-500);
+        fill: var(--google-blue-700);
       }
 
       .menu-trigger span {
@@ -65,13 +65,13 @@
       }
 
       paper-ripple {
-        color: var(--google-blue-500);
+        color: var(--google-blue-700);
         opacity: .5;
       }
 
       .page-menu paper-menu {
         --paper-menu-selected-item: {
-          color: var(--google-blue-500);
+          color: var(--google-blue-700);
           font-weight: 500;
         };
       }
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM
index 8318463..b75463c4 100644
--- a/chromeos/CHROMEOS_LKGM
+++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@
-9076.0.0
\ No newline at end of file
+9079.0.0
\ No newline at end of file
diff --git a/components/autofill/core/common/password_form.cc b/components/autofill/core/common/password_form.cc
index 17db566..3969e1f 100644
--- a/components/autofill/core/common/password_form.cc
+++ b/components/autofill/core/common/password_form.cc
@@ -145,8 +145,9 @@
           left.password_element == right.password_element);
 }
 
-bool LessThanUniqueKey::operator()(const PasswordForm* left,
-                                   const PasswordForm* right) const {
+bool LessThanUniqueKey::operator()(
+    const std::unique_ptr<PasswordForm>& left,
+    const std::unique_ptr<PasswordForm>& right) const {
   int result = left->signon_realm.compare(right->signon_realm);
   if (result)
     return result < 0;
diff --git a/components/autofill/core/common/password_form.h b/components/autofill/core/common/password_form.h
index c70da90..be74b85 100644
--- a/components/autofill/core/common/password_form.h
+++ b/components/autofill/core/common/password_form.h
@@ -293,7 +293,8 @@
 
 // A comparator for the unique key.
 struct LessThanUniqueKey {
-  bool operator()(const PasswordForm* left, const PasswordForm* right) const;
+  bool operator()(const std::unique_ptr<PasswordForm>& left,
+                  const std::unique_ptr<PasswordForm>& right) const;
 };
 
 // For testing.
diff --git a/components/exo/keyboard.cc b/components/exo/keyboard.cc
index 206b61f7..b6882f8 100644
--- a/components/exo/keyboard.cc
+++ b/components/exo/keyboard.cc
@@ -114,6 +114,10 @@
   helper->RemoveInputDeviceEventObserver(this);
 }
 
+bool Keyboard::HasDeviceConfigurationDelegate() const {
+  return !!device_configuration_delegate_;
+}
+
 void Keyboard::SetDeviceConfigurationDelegate(
     KeyboardDeviceConfigurationDelegate* delegate) {
   device_configuration_delegate_ = delegate;
diff --git a/components/exo/keyboard.h b/components/exo/keyboard.h
index 7e86dce..b56834f 100644
--- a/components/exo/keyboard.h
+++ b/components/exo/keyboard.h
@@ -33,6 +33,7 @@
   explicit Keyboard(KeyboardDelegate* delegate);
   ~Keyboard() override;
 
+  bool HasDeviceConfigurationDelegate() const;
   void SetDeviceConfigurationDelegate(
       KeyboardDeviceConfigurationDelegate* delegate);
 
diff --git a/components/exo/wayland/server.cc b/components/exo/wayland/server.cc
index f3fc2af..3b754f57 100644
--- a/components/exo/wayland/server.cc
+++ b/components/exo/wayland/server.cc
@@ -3058,7 +3058,16 @@
     wl_resource* resource,
     uint32_t id,
     wl_resource* keyboard_resource) {
-  // TODO(yhanada): Produce an error if a delegate already exists.
+  Keyboard* keyboard = GetUserDataAs<Keyboard>(keyboard_resource);
+  if (keyboard->HasDeviceConfigurationDelegate()) {
+    wl_resource_post_error(
+        resource,
+        ZCR_KEYBOARD_CONFIGURATION_V1_ERROR_DEVICE_CONFIGURATION_EXISTS,
+        "keyboard has already been associated with a device configuration "
+        "object");
+    return;
+  }
+
   wl_resource* keyboard_device_configuration_resource = wl_resource_create(
       client, &zcr_keyboard_device_configuration_v1_interface, 1, id);
 
@@ -3066,8 +3075,7 @@
       keyboard_device_configuration_resource,
       &keyboard_device_configuration_implementation,
       base::MakeUnique<WaylandKeyboardDeviceConfigurationDelegate>(
-          keyboard_device_configuration_resource,
-          GetUserDataAs<Keyboard>(keyboard_resource)));
+          keyboard_device_configuration_resource, keyboard));
 }
 
 const struct zcr_keyboard_configuration_v1_interface
@@ -3127,7 +3135,7 @@
   wl_global_create(wl_display_.get(), &zcr_stylus_v1_interface, 1, display_,
                    bind_stylus);
   wl_global_create(wl_display_.get(), &zcr_keyboard_configuration_v1_interface,
-                   1, display_, bind_keyboard_configuration);
+                   2, display_, bind_keyboard_configuration);
 }
 
 Server::~Server() {}
diff --git a/components/password_manager/core/browser/login_database.cc b/components/password_manager/core/browser/login_database.cc
index b7950ad..b3f9404 100644
--- a/components/password_manager/core/browser/login_database.cc
+++ b/components/password_manager/core/browser/login_database.cc
@@ -910,7 +910,7 @@
 bool LoginDatabase::RemoveLoginsCreatedBetween(base::Time delete_begin,
                                                base::Time delete_end) {
 #if defined(OS_IOS)
-  ScopedVector<autofill::PasswordForm> forms;
+  std::vector<std::unique_ptr<PasswordForm>> forms;
   if (GetLoginsCreatedBetween(delete_begin, delete_end, &forms)) {
     for (size_t i = 0; i < forms.size(); i++) {
       DeleteEncryptedPassword(*forms[i]);
@@ -942,7 +942,7 @@
 }
 
 bool LoginDatabase::GetAutoSignInLogins(
-    ScopedVector<autofill::PasswordForm>* forms) const {
+    std::vector<std::unique_ptr<PasswordForm>>* forms) const {
   DCHECK(forms);
   DCHECK(!autosignin_statement_.empty());
   sql::Statement s(
@@ -1035,7 +1035,7 @@
 
 bool LoginDatabase::GetLogins(
     const PasswordStore::FormDigest& form,
-    std::vector<std::unique_ptr<autofill::PasswordForm>>* forms) const {
+    std::vector<std::unique_ptr<PasswordForm>>* forms) const {
   DCHECK(forms);
   const GURL signon_realm(form.signon_realm);
   std::string registered_domain = GetRegistryControlledDomain(signon_realm);
@@ -1099,15 +1099,11 @@
                               PSL_DOMAIN_MATCH_COUNT);
   }
 
-  ScopedVector<autofill::PasswordForm> forms_scopedvector;
   bool success = StatementToForms(
       &s, should_PSL_matching_apply || should_federated_apply ? &form : nullptr,
-      &forms_scopedvector);
-  if (success) {
-    *forms = password_manager_util::ConvertScopedVector(
-        std::move(forms_scopedvector));
+      forms);
+  if (success)
     return true;
-  }
   forms->clear();
   return false;
 }
@@ -1115,7 +1111,7 @@
 bool LoginDatabase::GetLoginsCreatedBetween(
     const base::Time begin,
     const base::Time end,
-    ScopedVector<autofill::PasswordForm>* forms) const {
+    std::vector<std::unique_ptr<PasswordForm>>* forms) const {
   DCHECK(forms);
   DCHECK(!created_statement_.empty());
   sql::Statement s(
@@ -1130,7 +1126,7 @@
 bool LoginDatabase::GetLoginsSyncedBetween(
     const base::Time begin,
     const base::Time end,
-    ScopedVector<autofill::PasswordForm>* forms) const {
+    std::vector<std::unique_ptr<PasswordForm>>* forms) const {
   DCHECK(forms);
   DCHECK(!synced_statement_.empty());
   sql::Statement s(
@@ -1144,12 +1140,12 @@
 }
 
 bool LoginDatabase::GetAutofillableLogins(
-    std::vector<std::unique_ptr<autofill::PasswordForm>>* forms) const {
+    std::vector<std::unique_ptr<PasswordForm>>* forms) const {
   return GetAllLoginsWithBlacklistSetting(false, forms);
 }
 
 bool LoginDatabase::GetBlacklistLogins(
-    std::vector<std::unique_ptr<autofill::PasswordForm>>* forms) const {
+    std::vector<std::unique_ptr<PasswordForm>>* forms) const {
   return GetAllLoginsWithBlacklistSetting(true, forms);
 }
 
@@ -1162,13 +1158,9 @@
       db_.GetCachedStatement(SQL_FROM_HERE, blacklisted_statement_.c_str()));
   s.BindInt(0, blacklisted ? 1 : 0);
 
-  ScopedVector<autofill::PasswordForm> forms_scopedvector;
-  bool success = StatementToForms(&s, nullptr, &forms_scopedvector);
-  if (success) {
-    *forms = password_manager_util::ConvertScopedVector(
-        std::move(forms_scopedvector));
+  bool success = StatementToForms(&s, nullptr, forms);
+  if (success)
     return true;
-  }
   forms->clear();
   return false;
 }
@@ -1182,7 +1174,7 @@
 }
 
 std::string LoginDatabase::GetEncryptedPassword(
-    const autofill::PasswordForm& form) const {
+    const PasswordForm& form) const {
   DCHECK(!encrypted_statement_.empty());
   sql::Statement s(
       db_.GetCachedStatement(SQL_FROM_HERE, encrypted_statement_.c_str()));
@@ -1204,12 +1196,12 @@
 bool LoginDatabase::StatementToForms(
     sql::Statement* statement,
     const PasswordStore::FormDigest* matched_form,
-    ScopedVector<autofill::PasswordForm>* forms) {
+    std::vector<std::unique_ptr<PasswordForm>>* forms) {
   PSLDomainMatchMetric psl_domain_match_metric = PSL_DOMAIN_MATCH_NONE;
 
   forms->clear();
   while (statement->Step()) {
-    std::unique_ptr<PasswordForm> new_form(new PasswordForm());
+    auto new_form = base::MakeUnique<PasswordForm>();
     EncryptionResult result =
         InitPasswordFormFromStatement(new_form.get(), *statement);
     if (result == ENCRYPTION_RESULT_SERVICE_FAILURE)
diff --git a/components/password_manager/core/browser/login_database.h b/components/password_manager/core/browser/login_database.h
index 4be14f0..c6cf73dc 100644
--- a/components/password_manager/core/browser/login_database.h
+++ b/components/password_manager/core/browser/login_database.h
@@ -12,7 +12,6 @@
 #include "base/compiler_specific.h"
 #include "base/files/file_path.h"
 #include "base/macros.h"
-#include "base/memory/scoped_vector.h"
 #include "base/pickle.h"
 #include "base/strings/string16.h"
 #include "build/build_config.h"
@@ -98,14 +97,16 @@
   bool GetLoginsCreatedBetween(
       base::Time begin,
       base::Time end,
-      ScopedVector<autofill::PasswordForm>* forms) const WARN_UNUSED_RESULT;
+      std::vector<std::unique_ptr<autofill::PasswordForm>>* forms) const
+      WARN_UNUSED_RESULT;
 
   // Gets all logins synced from |begin| onwards (inclusive) and before |end|.
   // You may use a null Time value to do an unbounded search in either
   // direction.
-  bool GetLoginsSyncedBetween(base::Time begin,
-                              base::Time end,
-                              ScopedVector<autofill::PasswordForm>* forms) const
+  bool GetLoginsSyncedBetween(
+      base::Time begin,
+      base::Time end,
+      std::vector<std::unique_ptr<autofill::PasswordForm>>* forms) const
       WARN_UNUSED_RESULT;
 
   // Gets the complete list of not blacklisted credentials.
@@ -118,8 +119,8 @@
                               forms) const WARN_UNUSED_RESULT;
 
   // Gets the list of auto-sign-inable credentials.
-  bool GetAutoSignInLogins(ScopedVector<autofill::PasswordForm>* forms) const
-      WARN_UNUSED_RESULT;
+  bool GetAutoSignInLogins(std::vector<std::unique_ptr<autofill::PasswordForm>>*
+                               forms) const WARN_UNUSED_RESULT;
 
   // Deletes the login database file on disk, and creates a new, empty database.
   // This can be used after migrating passwords to some other store, to ensure
@@ -192,9 +193,10 @@
   // Overwrites |forms| with credentials retrieved from |statement|. If
   // |matched_form| is not null, filters out all results but those PSL-matching
   // |*matched_form| or federated credentials for it. On success returns true.
-  static bool StatementToForms(sql::Statement* statement,
-                               const PasswordStore::FormDigest* matched_form,
-                               ScopedVector<autofill::PasswordForm>* forms);
+  static bool StatementToForms(
+      sql::Statement* statement,
+      const PasswordStore::FormDigest* matched_form,
+      std::vector<std::unique_ptr<autofill::PasswordForm>>* forms);
 
   // Initializes all the *_statement_ data members with appropriate SQL
   // fragments based on |builder|.
diff --git a/components/password_manager/core/browser/login_database_ios_unittest.cc b/components/password_manager/core/browser/login_database_ios_unittest.cc
index b604d67..4ada9cf 100644
--- a/components/password_manager/core/browser/login_database_ios_unittest.cc
+++ b/components/password_manager/core/browser/login_database_ios_unittest.cc
@@ -116,7 +116,7 @@
       login_db_->UpdateLogin(form);
   ASSERT_EQ(1u, changes.size());
 
-  ScopedVector<PasswordForm> forms;
+  std::vector<std::unique_ptr<PasswordForm>> forms;
   EXPECT_TRUE(login_db_->GetLogins(PasswordStore::FormDigest(form), &forms));
 
   ASSERT_EQ(1U, forms.size());
@@ -135,7 +135,7 @@
 
   ignore_result(login_db_->RemoveLogin(form));
 
-  ScopedVector<PasswordForm> forms;
+  std::vector<std::unique_ptr<PasswordForm>> forms;
   EXPECT_TRUE(login_db_->GetLogins(PasswordStore::FormDigest(form), &forms));
 
   ASSERT_EQ(0U, forms.size());
@@ -171,7 +171,7 @@
 
   PasswordStore::FormDigest form = {PasswordForm::SCHEME_HTML,
                                     "http://www.example.com", GURL()};
-  ScopedVector<PasswordForm> logins;
+  std::vector<std::unique_ptr<PasswordForm>> logins;
   EXPECT_TRUE(login_db_->GetLogins(form, &logins));
 
   ASSERT_EQ(2U, logins.size());
diff --git a/components/password_manager/core/browser/login_database_unittest.cc b/components/password_manager/core/browser/login_database_unittest.cc
index 757e82e..248f70c 100644
--- a/components/password_manager/core/browser/login_database_unittest.cc
+++ b/components/password_manager/core/browser/login_database_unittest.cc
@@ -12,7 +12,6 @@
 
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
-#include "base/memory/scoped_vector.h"
 #include "base/path_service.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
@@ -401,7 +400,7 @@
   form2.action = GURL("https://mobile.foo.com/login");
   form2.signon_realm = "federation://mobile.foo.com/accounts.google.com";
   form2.username_value = ASCIIToUTF16("test1@gmail.com");
-  form2.type = autofill::PasswordForm::TYPE_API;
+  form2.type = PasswordForm::TYPE_API;
   form2.federation_origin = url::Origin(GURL("https://accounts.google.com/"));
 
   // Add it and make sure it is there.
@@ -510,7 +509,7 @@
   form2.action = GURL("https://some.other.google.com/login");
   form2.signon_realm = "federation://some.other.google.com/accounts.google.com";
   form2.username_value = ASCIIToUTF16("test1@gmail.com");
-  form2.type = autofill::PasswordForm::TYPE_API;
+  form2.type = PasswordForm::TYPE_API;
   form2.federation_origin = url::Origin(GURL("https://accounts.google.com/"));
 
   // Add it and make sure it is there.
@@ -780,13 +779,10 @@
   EXPECT_EQ(4U, result.size());
   result.clear();
 
-  // TODO(crbug.com/555132) Replace |result_scopedvector| back with |result|.
-  ScopedVector<PasswordForm> result_scopedvector;
   // Get everything from today's date and on.
-  EXPECT_TRUE(
-      db().GetLoginsCreatedBetween(now, base::Time(), &result_scopedvector));
-  EXPECT_EQ(2U, result_scopedvector.size());
-  result_scopedvector.clear();
+  EXPECT_TRUE(db().GetLoginsCreatedBetween(now, base::Time(), &result));
+  EXPECT_EQ(2U, result.size());
+  result.clear();
 
   // Delete everything from today's date and on.
   db().RemoveLoginsCreatedBetween(now, base::Time());
@@ -825,15 +821,12 @@
   EXPECT_EQ(4U, result.size());
   result.clear();
 
-  // TODO(crbug.com/555132) Replace |result_scopedvector| back with |result|.
-  ScopedVector<PasswordForm> result_scopedvector;
   // Get everything from today's date and on.
-  EXPECT_TRUE(
-      db().GetLoginsSyncedBetween(now, base::Time(), &result_scopedvector));
-  ASSERT_EQ(2U, result_scopedvector.size());
-  EXPECT_EQ("http://3.com", result_scopedvector[0]->signon_realm);
-  EXPECT_EQ("http://4.com", result_scopedvector[1]->signon_realm);
-  result_scopedvector.clear();
+  EXPECT_TRUE(db().GetLoginsSyncedBetween(now, base::Time(), &result));
+  ASSERT_EQ(2U, result.size());
+  EXPECT_EQ("http://3.com", result[0]->signon_realm);
+  EXPECT_EQ("http://4.com", result[1]->signon_realm);
+  result.clear();
 
   // Delete everything from today's date and on.
   db().RemoveLoginsSyncedBetween(now, base::Time());
@@ -854,7 +847,7 @@
 }
 
 TEST_F(LoginDatabaseTest, GetAutoSignInLogins) {
-  ScopedVector<PasswordForm> result;
+  std::vector<std::unique_ptr<PasswordForm>> result;
 
   GURL origin("https://example.com");
   EXPECT_TRUE(AddZeroClickableLogin(&db(), "foo1", origin));
@@ -864,7 +857,7 @@
 
   EXPECT_TRUE(db().GetAutoSignInLogins(&result));
   EXPECT_EQ(4U, result.size());
-  for (const auto* form : result)
+  for (const auto& form : result)
     EXPECT_FALSE(form->skip_zero_click);
 
   EXPECT_TRUE(db().DisableAutoSignInForOrigin(origin));
diff --git a/components/password_manager/core/browser/password_form_manager.h b/components/password_manager/core/browser/password_form_manager.h
index f46d4012..153f7918 100644
--- a/components/password_manager/core/browser/password_form_manager.h
+++ b/components/password_manager/core/browser/password_form_manager.h
@@ -13,7 +13,6 @@
 #include <vector>
 
 #include "base/macros.h"
-#include "base/memory/scoped_vector.h"
 #include "base/memory/weak_ptr.h"
 #include "base/optional.h"
 #include "base/strings/string16.h"
diff --git a/components/password_manager/core/browser/password_manager_util.cc b/components/password_manager/core/browser/password_manager_util.cc
index 6383418..ae5e3fc3 100644
--- a/components/password_manager/core/browser/password_manager_util.cc
+++ b/components/password_manager/core/browser/password_manager_util.cc
@@ -26,8 +26,8 @@
 }
 
 void FindDuplicates(
-    ScopedVector<autofill::PasswordForm>* forms,
-    ScopedVector<autofill::PasswordForm>* duplicates,
+    std::vector<std::unique_ptr<autofill::PasswordForm>>* forms,
+    std::vector<std::unique_ptr<autofill::PasswordForm>>* duplicates,
     std::vector<std::vector<autofill::PasswordForm*>>* tag_groups) {
   if (forms->empty())
     return;
@@ -36,27 +36,25 @@
   // duplicates. Therefore, the caller should try to preserve it.
   std::stable_sort(forms->begin(), forms->end(), autofill::LessThanUniqueKey());
 
-  ScopedVector<autofill::PasswordForm> unique_forms;
-  unique_forms.push_back(forms->front());
-  forms->front() = nullptr;
+  std::vector<std::unique_ptr<autofill::PasswordForm>> unique_forms;
+  unique_forms.push_back(std::move(forms->front()));
   if (tag_groups) {
     tag_groups->clear();
     tag_groups->push_back(std::vector<autofill::PasswordForm*>());
-    tag_groups->front().push_back(unique_forms.front());
+    tag_groups->front().push_back(unique_forms.front().get());
   }
   for (auto it = forms->begin() + 1; it != forms->end(); ++it) {
     if (ArePasswordFormUniqueKeyEqual(**it, *unique_forms.back())) {
-      duplicates->push_back(*it);
       if (tag_groups)
-        tag_groups->back().push_back(*it);
+        tag_groups->back().push_back(it->get());
+      duplicates->push_back(std::move(*it));
     } else {
-      unique_forms.push_back(*it);
       if (tag_groups)
-        tag_groups->push_back(std::vector<autofill::PasswordForm*>(1, *it));
+        tag_groups->push_back(
+            std::vector<autofill::PasswordForm*>(1, it->get()));
+      unique_forms.push_back(std::move(*it));
     }
-    *it = nullptr;
   }
-  forms->weak_clear();
   forms->swap(unique_forms);
 }
 
@@ -82,17 +80,6 @@
       });
 }
 
-std::vector<std::unique_ptr<autofill::PasswordForm>> ConvertScopedVector(
-    ScopedVector<autofill::PasswordForm> old_vector) {
-  std::vector<std::unique_ptr<autofill::PasswordForm>> new_vector;
-  new_vector.reserve(old_vector.size());
-  for (auto* form : old_vector) {
-    new_vector.push_back(base::WrapUnique(form));
-  }
-  old_vector.weak_clear();  // All owned by |new_vector| by now.
-  return new_vector;
-}
-
 bool IsLoggingActive(const password_manager::PasswordManagerClient* client) {
   const password_manager::LogManager* log_manager = client->GetLogManager();
   return log_manager && log_manager->IsLoggingActive();
diff --git a/components/password_manager/core/browser/password_manager_util.h b/components/password_manager/core/browser/password_manager_util.h
index 8a1365c7..68fc65b 100644
--- a/components/password_manager/core/browser/password_manager_util.h
+++ b/components/password_manager/core/browser/password_manager_util.h
@@ -9,7 +9,6 @@
 #include <vector>
 
 #include "base/callback.h"
-#include "base/memory/scoped_vector.h"
 #include "components/password_manager/core/browser/password_manager_client.h"
 #include "ui/gfx/native_widget_types.h"
 
@@ -35,8 +34,8 @@
 // the sync tag. The first element in each group is one from |forms|. It's
 // followed by the duplicates.
 void FindDuplicates(
-    ScopedVector<autofill::PasswordForm>* forms,
-    ScopedVector<autofill::PasswordForm>* duplicates,
+    std::vector<std::unique_ptr<autofill::PasswordForm>>* forms,
+    std::vector<std::unique_ptr<autofill::PasswordForm>>* duplicates,
     std::vector<std::vector<autofill::PasswordForm*>>* tag_groups);
 
 // Removes Android username-only credentials from |android_credentials|.
@@ -44,11 +43,6 @@
 void TrimUsernameOnlyCredentials(
     std::vector<std::unique_ptr<autofill::PasswordForm>>* android_credentials);
 
-// TODO(crbug.com/555132): Remove this when the migration from ScopedVector is
-// finished for PasswordForm.
-std::vector<std::unique_ptr<autofill::PasswordForm>> ConvertScopedVector(
-    ScopedVector<autofill::PasswordForm> old_vector);
-
 // A convenience function for testing that |client| has a non-null LogManager
 // and that that LogManager returns true for IsLoggingActive. This function can
 // be removed once PasswordManagerClient::GetLogManager is implemented on iOS
diff --git a/components/password_manager/core/browser/password_store_default.cc b/components/password_manager/core/browser/password_store_default.cc
index 5588faaf..e01ab22 100644
--- a/components/password_manager/core/browser/password_store_default.cc
+++ b/components/password_manager/core/browser/password_store_default.cc
@@ -84,11 +84,11 @@
     const base::Callback<bool(const GURL&)>& url_filter,
     base::Time delete_begin,
     base::Time delete_end) {
-  ScopedVector<autofill::PasswordForm> forms;
+  std::vector<std::unique_ptr<PasswordForm>> forms;
   PasswordStoreChangeList changes;
   if (login_db_ &&
       login_db_->GetLoginsCreatedBetween(delete_begin, delete_end, &forms)) {
-    for (autofill::PasswordForm* form : forms) {
+    for (const auto& form : forms) {
       if (url_filter.Run(form->origin) && login_db_->RemoveLogin(*form))
         changes.push_back(
             PasswordStoreChange(PasswordStoreChange::REMOVE, *form));
@@ -102,12 +102,12 @@
 PasswordStoreChangeList PasswordStoreDefault::RemoveLoginsCreatedBetweenImpl(
     base::Time delete_begin,
     base::Time delete_end) {
-  ScopedVector<autofill::PasswordForm> forms;
+  std::vector<std::unique_ptr<PasswordForm>> forms;
   PasswordStoreChangeList changes;
   if (login_db_ &&
       login_db_->GetLoginsCreatedBetween(delete_begin, delete_end, &forms)) {
     if (login_db_->RemoveLoginsCreatedBetween(delete_begin, delete_end)) {
-      for (const auto* form : forms) {
+      for (const auto& form : forms) {
         changes.push_back(
             PasswordStoreChange(PasswordStoreChange::REMOVE, *form));
       }
@@ -120,12 +120,12 @@
 PasswordStoreChangeList PasswordStoreDefault::RemoveLoginsSyncedBetweenImpl(
     base::Time delete_begin,
     base::Time delete_end) {
-  ScopedVector<autofill::PasswordForm> forms;
+  std::vector<std::unique_ptr<PasswordForm>> forms;
   PasswordStoreChangeList changes;
   if (login_db_ &&
       login_db_->GetLoginsSyncedBetween(delete_begin, delete_end, &forms)) {
     if (login_db_->RemoveLoginsSyncedBetween(delete_begin, delete_end)) {
-      for (const auto* form : forms) {
+      for (const auto& form : forms) {
         changes.push_back(
             PasswordStoreChange(PasswordStoreChange::REMOVE, *form));
       }
@@ -137,13 +137,13 @@
 
 PasswordStoreChangeList PasswordStoreDefault::DisableAutoSignInForOriginsImpl(
     const base::Callback<bool(const GURL&)>& origin_filter) {
-  ScopedVector<autofill::PasswordForm> forms;
+  std::vector<std::unique_ptr<PasswordForm>> forms;
   PasswordStoreChangeList changes;
   if (!login_db_ || !login_db_->GetAutoSignInLogins(&forms))
     return changes;
 
   std::set<GURL> origins_to_update;
-  for (const auto* form : forms) {
+  for (const auto& form : forms) {
     if (origin_filter.Run(form->origin))
       origins_to_update.insert(form->origin);
   }
@@ -154,7 +154,7 @@
       origins_updated.insert(origin);
   }
 
-  for (const auto* form : forms) {
+  for (const auto& form : forms) {
     if (origins_updated.count(form->origin)) {
       changes.push_back(
           PasswordStoreChange(PasswordStoreChange::UPDATE, *form));
diff --git a/components/password_manager/core/browser/password_store_sync.h b/components/password_manager/core/browser/password_store_sync.h
index 4d1b171c..fc8b55de 100644
--- a/components/password_manager/core/browser/password_store_sync.h
+++ b/components/password_manager/core/browser/password_store_sync.h
@@ -10,7 +10,6 @@
 
 #include "base/compiler_specific.h"
 #include "base/macros.h"
-#include "base/memory/scoped_vector.h"
 #include "components/password_manager/core/browser/password_store_change.h"
 
 namespace autofill {
diff --git a/components/password_manager/core/browser/password_store_unittest.cc b/components/password_manager/core/browser/password_store_unittest.cc
index ac3a74e7..c811bb4 100644
--- a/components/password_manager/core/browser/password_store_unittest.cc
+++ b/components/password_manager/core/browser/password_store_unittest.cc
@@ -136,7 +136,7 @@
   };
 
   // Build the forms vector and add the forms to the store.
-  ScopedVector<PasswordForm> all_forms;
+  std::vector<std::unique_ptr<PasswordForm>> all_forms;
   for (size_t i = 0; i < arraysize(form_data); ++i) {
     all_forms.push_back(CreatePasswordFormFromDataForTesting(form_data[i]));
     store->AddLogin(*all_forms.back());
@@ -398,7 +398,7 @@
   MockAffiliatedMatchHelper* mock_helper = new MockAffiliatedMatchHelper;
   store->SetAffiliatedMatchHelper(base::WrapUnique(mock_helper));
 
-  ScopedVector<PasswordForm> all_credentials;
+  std::vector<std::unique_ptr<PasswordForm>> all_credentials;
   for (size_t i = 0; i < arraysize(kTestCredentials); ++i) {
     all_credentials.push_back(
         CreatePasswordFormFromDataForTesting(kTestCredentials[i]));
@@ -503,7 +503,7 @@
   MockAffiliatedMatchHelper* mock_helper = new MockAffiliatedMatchHelper;
   store->SetAffiliatedMatchHelper(base::WrapUnique(mock_helper));
 
-  ScopedVector<PasswordForm> all_credentials;
+  std::vector<std::unique_ptr<PasswordForm>> all_credentials;
   for (size_t i = 0; i < arraysize(kTestCredentials); ++i) {
     all_credentials.push_back(
         CreatePasswordFormFromDataForTesting(kTestCredentials[i]));
@@ -687,7 +687,7 @@
                                         base::Closure());
 
       // Set up the initial test data set.
-      ScopedVector<PasswordForm> all_credentials;
+      std::vector<std::unique_ptr<PasswordForm>> all_credentials;
       for (size_t i = 0; i < arraysize(kTestCredentials); ++i) {
         all_credentials.push_back(
             CreatePasswordFormFromDataForTesting(kTestCredentials[i]));
@@ -795,7 +795,7 @@
     store->RemoveLoginsCreatedBetween(base::Time(), base::Time::Max(),
                                       base::Closure());
 
-    ScopedVector<PasswordForm> all_credentials;
+    std::vector<std::unique_ptr<PasswordForm>> all_credentials;
     for (size_t i = 0; i < arraysize(kTestCredentials); ++i) {
       all_credentials.push_back(
           CreatePasswordFormFromDataForTesting(kTestCredentials[i]));
diff --git a/components/password_manager/core/browser/statistics_table.h b/components/password_manager/core/browser/statistics_table.h
index 57d7070..ea6c8c1 100644
--- a/components/password_manager/core/browser/statistics_table.h
+++ b/components/password_manager/core/browser/statistics_table.h
@@ -10,7 +10,6 @@
 
 #include "base/callback_forward.h"
 #include "base/macros.h"
-#include "base/memory/scoped_vector.h"
 #include "base/time/time.h"
 #include "url/gurl.h"
 
diff --git a/components/password_manager/sync/browser/sync_credentials_filter_unittest.cc b/components/password_manager/sync/browser/sync_credentials_filter_unittest.cc
index a74a471..2830c55 100644
--- a/components/password_manager/sync/browser/sync_credentials_filter_unittest.cc
+++ b/components/password_manager/sync/browser/sync_credentials_filter_unittest.cc
@@ -14,7 +14,6 @@
 #include "base/bind_helpers.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/strings/utf_string_conversions.h"
 #include "base/test/histogram_tester.h"
diff --git a/components/reading_list/core/BUILD.gn b/components/reading_list/core/BUILD.gn
index 52dbc373..f45b10c 100644
--- a/components/reading_list/core/BUILD.gn
+++ b/components/reading_list/core/BUILD.gn
@@ -2,12 +2,22 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import("//build/buildflag_header.gni")
+import("//components/reading_list/core/reading_list.gni")
+
 source_set("core") {
   sources = [
     "reading_list_switches.cc",
     "reading_list_switches.h",
   ]
   deps = [
+    ":reading_list_enable_flags",
     "//base",
   ]
 }
+
+buildflag_header("reading_list_enable_flags") {
+  header = "reading_list_enable_flags.h"
+  _enabled = is_ios && enable_reading_list
+  flags = [ "ENABLE_READING_LIST=$_enabled" ]
+}
diff --git a/components/reading_list/core/reading_list.gni b/components/reading_list/core/reading_list.gni
new file mode 100644
index 0000000..26c4e1e
--- /dev/null
+++ b/components/reading_list/core/reading_list.gni
@@ -0,0 +1,9 @@
+# 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.
+
+declare_args() {
+  # Controls whether reading list support is active or not. Currently only
+  # supported on iOS (on other platforms, the feature is always disabled).
+  enable_reading_list = true
+}
diff --git a/components/reading_list/core/reading_list_switches.cc b/components/reading_list/core/reading_list_switches.cc
index 4fa0804..d6aba34 100644
--- a/components/reading_list/core/reading_list_switches.cc
+++ b/components/reading_list/core/reading_list_switches.cc
@@ -6,23 +6,12 @@
 
 #include "build/build_config.h"
 #include "base/command_line.h"
+#include "components/reading_list/core/reading_list_enable_flags.h"
 
 namespace reading_list {
 namespace switches {
-// Enables the reading list.
-const char kEnableReadingList[] = "enable-reading-list";
-
-// Disables the reading list.
-const char kDisableReadingList[] = "disable-reading-list";
-
 bool IsReadingListEnabled() {
-  // Reading list is only enabled on iOS.
-#if defined(OS_IOS)
-  if (base::CommandLine::ForCurrentProcess()->HasSwitch(kEnableReadingList)) {
-    return true;
-  }
-#endif
-  return false;
+  return BUILDFLAG(ENABLE_READING_LIST);
 }
 }  // namespace switches
 }  // namespace reading_list
diff --git a/components/reading_list/core/reading_list_switches.h b/components/reading_list/core/reading_list_switches.h
index e9790fc..c99231c 100644
--- a/components/reading_list/core/reading_list_switches.h
+++ b/components/reading_list/core/reading_list_switches.h
@@ -7,9 +7,6 @@
 
 namespace reading_list {
 namespace switches {
-extern const char kEnableReadingList[];
-extern const char kDisableReadingList[];
-
 // Whether Reading List is enabled on this device.
 bool IsReadingListEnabled();
 }  // namespace switches
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index 95e2cfba..ba9ac056 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -878,8 +878,8 @@
     "media/capture/window_activity_tracker_aura.h",
     "media/capture/window_activity_tracker_mac.h",
     "media/capture/window_activity_tracker_mac.mm",
-    "media/cdm_service_impl.cc",
-    "media/cdm_service_impl.h",
+    "media/cdm_registry_impl.cc",
+    "media/cdm_registry_impl.h",
     "media/media_devices_permission_checker.cc",
     "media/media_devices_permission_checker.h",
     "media/media_interface_proxy.cc",
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc
index bea6dcc8..7f1e484b 100644
--- a/content/browser/browser_main_loop.cc
+++ b/content/browser/browser_main_loop.cc
@@ -190,7 +190,7 @@
 #endif
 
 #if defined(ENABLE_MOJO_CDM) && BUILDFLAG(ENABLE_PEPPER_CDMS)
-#include "content/browser/media/cdm_service_impl.h"
+#include "content/browser/media/cdm_registry_impl.h"
 #endif
 
 #if defined(USE_X11)
@@ -854,7 +854,7 @@
   // Prior to any processing happening on the IO thread, we create the
   // CDM service as it is predominantly used from the IO thread. This must
   // be called on the main thread since it involves file path checks.
-  CdmService::GetInstance()->Init();
+  CdmRegistry::GetInstance()->Init();
 #endif
 
 #if defined(OS_MACOSX)
diff --git a/content/browser/media/cdm_registry_impl.cc b/content/browser/media/cdm_registry_impl.cc
new file mode 100644
index 0000000..fba9689
--- /dev/null
+++ b/content/browser/media/cdm_registry_impl.cc
@@ -0,0 +1,46 @@
+// 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 "content/browser/media/cdm_registry_impl.h"
+
+#include <stddef.h>
+
+#include "content/public/common/cdm_info.h"
+#include "content/public/common/content_client.h"
+
+namespace content {
+
+static base::LazyInstance<CdmRegistryImpl>::Leaky g_cdm_registry =
+    LAZY_INSTANCE_INITIALIZER;
+
+// static
+CdmRegistry* CdmRegistry::GetInstance() {
+  return CdmRegistryImpl::GetInstance();
+}
+
+// static
+CdmRegistryImpl* CdmRegistryImpl::GetInstance() {
+  return g_cdm_registry.Pointer();
+}
+
+CdmRegistryImpl::CdmRegistryImpl() {}
+
+CdmRegistryImpl::~CdmRegistryImpl() {}
+
+void CdmRegistryImpl::Init() {
+  // Let embedders register CDMs.
+  GetContentClient()->AddContentDecryptionModules(&cdms_);
+}
+
+void CdmRegistryImpl::RegisterCdm(const CdmInfo& info) {
+  // Always register new CDMs at the beginning of the list, so that
+  // subsequent requests get the latest.
+  cdms_.insert(cdms_.begin(), info);
+}
+
+const std::vector<CdmInfo>& CdmRegistryImpl::GetAllRegisteredCdms() {
+  return cdms_;
+}
+
+}  // namespace media
diff --git a/content/browser/media/cdm_registry_impl.h b/content/browser/media/cdm_registry_impl.h
new file mode 100644
index 0000000..0313bfe
--- /dev/null
+++ b/content/browser/media/cdm_registry_impl.h
@@ -0,0 +1,43 @@
+// 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 CONTENT_BROWSER_MEDIA_CDM_REGISTRY_IMPL_H_
+#define CONTENT_BROWSER_MEDIA_CDM_REGISTRY_IMPL_H_
+
+#include <vector>
+
+#include "base/lazy_instance.h"
+#include "base/macros.h"
+#include "content/common/content_export.h"
+#include "content/public/browser/cdm_registry.h"
+
+namespace content {
+
+struct CdmInfo;
+
+class CONTENT_EXPORT CdmRegistryImpl : NON_EXPORTED_BASE(public CdmRegistry) {
+ public:
+  // Returns the CdmRegistryImpl singleton.
+  static CdmRegistryImpl* GetInstance();
+
+  // CdmRegistry implementation.
+  void Init() override;
+  void RegisterCdm(const CdmInfo& info) override;
+  const std::vector<CdmInfo>& GetAllRegisteredCdms() override;
+
+ private:
+  friend struct base::DefaultLazyInstanceTraits<CdmRegistryImpl>;
+  friend class CdmRegistryImplTest;
+
+  CdmRegistryImpl();
+  ~CdmRegistryImpl() override;
+
+  std::vector<CdmInfo> cdms_;
+
+  DISALLOW_COPY_AND_ASSIGN(CdmRegistryImpl);
+};
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_MEDIA_CDM_REGISTRY_IMPL_H_
diff --git a/content/browser/media/cdm_service_impl_unittest.cc b/content/browser/media/cdm_registry_impl_unittest.cc
similarity index 80%
rename from content/browser/media/cdm_service_impl_unittest.cc
rename to content/browser/media/cdm_registry_impl_unittest.cc
index 0d336a4..91cac24 100644
--- a/content/browser/media/cdm_service_impl_unittest.cc
+++ b/content/browser/media/cdm_registry_impl_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/browser/media/cdm_service_impl.h"
+#include "content/browser/media/cdm_registry_impl.h"
 
 #include <algorithm>
 #include <string>
@@ -28,10 +28,10 @@
 
 // For simplicity and to make failures easier to diagnose, this test uses
 // std::string instead of base::FilePath and std::vector<std::string>.
-class CdmServiceImplTest : public testing::Test {
+class CdmRegistryImplTest : public testing::Test {
  public:
-  CdmServiceImplTest() {}
-  ~CdmServiceImplTest() override {}
+  CdmRegistryImplTest() {}
+  ~CdmRegistryImplTest() override {}
 
  protected:
   void Register(const std::string& type,
@@ -41,13 +41,13 @@
     const std::vector<std::string> codecs =
         base::SplitString(supported_codecs, kCodecDelimiter,
                           base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
-    cdm_service_.RegisterCdm(CdmInfo(type, base::Version(version),
-                                     base::FilePath::FromUTF8Unsafe(path),
-                                     codecs));
+    cdm_registry_.RegisterCdm(CdmInfo(type, base::Version(version),
+                                      base::FilePath::FromUTF8Unsafe(path),
+                                      codecs));
   }
 
   bool IsRegistered(const std::string& type, const std::string& version) {
-    for (const auto& cdm : cdm_service_.GetAllRegisteredCdms()) {
+    for (const auto& cdm : cdm_registry_.GetAllRegisteredCdms()) {
       if (cdm.type == type && cdm.version.GetString() == version)
         return true;
     }
@@ -56,7 +56,7 @@
 
   std::vector<std::string> GetVersions(const std::string& type) {
     std::vector<std::string> versions;
-    for (const auto& cdm : cdm_service_.GetAllRegisteredCdms()) {
+    for (const auto& cdm : cdm_registry_.GetAllRegisteredCdms()) {
       if (cdm.type == type)
         versions.push_back(cdm.version.GetString());
     }
@@ -64,19 +64,19 @@
   }
 
  private:
-  CdmServiceImpl cdm_service_;
+  CdmRegistryImpl cdm_registry_;
 };
 
 // Note that KeySystemService is a singleton, and thus the actions of
 // one test impact other tests. So each test defines a different key system
 // name to avoid conflicts.
 
-TEST_F(CdmServiceImplTest, Register) {
+TEST_F(CdmRegistryImplTest, Register) {
   Register(kTestKeySystemType, kVersion1, kTestPath, kTestCodecs);
   EXPECT_TRUE(IsRegistered(kTestKeySystemType, kVersion1));
 }
 
-TEST_F(CdmServiceImplTest, ReRegister) {
+TEST_F(CdmRegistryImplTest, ReRegister) {
   Register(kTestKeySystemType, kVersion1, "/bb/cc", "unknown");
   EXPECT_TRUE(IsRegistered(kTestKeySystemType, kVersion1));
 
@@ -85,14 +85,14 @@
   EXPECT_TRUE(IsRegistered(kTestKeySystemType, kVersion1));
 }
 
-TEST_F(CdmServiceImplTest, MultipleVersions) {
+TEST_F(CdmRegistryImplTest, MultipleVersions) {
   Register(kTestKeySystemType, kVersion1, kTestPath, kTestCodecs);
   Register(kTestKeySystemType, kVersion2, "/bb/cc", "unknown");
   EXPECT_TRUE(IsRegistered(kTestKeySystemType, kVersion1));
   EXPECT_TRUE(IsRegistered(kTestKeySystemType, kVersion2));
 }
 
-TEST_F(CdmServiceImplTest, NewVersionInsertedFirst) {
+TEST_F(CdmRegistryImplTest, NewVersionInsertedFirst) {
   Register(kTestKeySystemType, kVersion1, kTestPath, kTestCodecs);
   Register(kTestKeySystemType, kVersion2, "/bb/cc", "unknown");
 
diff --git a/content/browser/media/cdm_service_impl.cc b/content/browser/media/cdm_service_impl.cc
deleted file mode 100644
index 87e5c52..0000000
--- a/content/browser/media/cdm_service_impl.cc
+++ /dev/null
@@ -1,46 +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 "content/browser/media/cdm_service_impl.h"
-
-#include <stddef.h>
-
-#include "content/public/common/cdm_info.h"
-#include "content/public/common/content_client.h"
-
-namespace content {
-
-static base::LazyInstance<CdmServiceImpl>::Leaky g_cdm_service =
-    LAZY_INSTANCE_INITIALIZER;
-
-// static
-CdmService* CdmService::GetInstance() {
-  return CdmServiceImpl::GetInstance();
-}
-
-// static
-CdmServiceImpl* CdmServiceImpl::GetInstance() {
-  return g_cdm_service.Pointer();
-}
-
-CdmServiceImpl::CdmServiceImpl() {}
-
-CdmServiceImpl::~CdmServiceImpl() {}
-
-void CdmServiceImpl::Init() {
-  // Let embedders register CDMs.
-  GetContentClient()->AddContentDecryptionModules(&cdms_);
-}
-
-void CdmServiceImpl::RegisterCdm(const CdmInfo& info) {
-  // Always register new CDMs at the beginning of the list, so that
-  // subsequent requests get the latest.
-  cdms_.insert(cdms_.begin(), info);
-}
-
-const std::vector<CdmInfo>& CdmServiceImpl::GetAllRegisteredCdms() {
-  return cdms_;
-}
-
-}  // namespace media
diff --git a/content/browser/media/cdm_service_impl.h b/content/browser/media/cdm_service_impl.h
deleted file mode 100644
index 97f873c..0000000
--- a/content/browser/media/cdm_service_impl.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_MEDIA_CDM_SERVICE_IMPL_H_
-#define CONTENT_BROWSER_MEDIA_CDM_SERVICE_IMPL_H_
-
-#include <vector>
-
-#include "base/lazy_instance.h"
-#include "base/macros.h"
-#include "content/common/content_export.h"
-#include "content/public/browser/cdm_service.h"
-
-namespace content {
-
-struct CdmInfo;
-
-class CONTENT_EXPORT CdmServiceImpl : NON_EXPORTED_BASE(public CdmService) {
- public:
-  // Returns the CdmServiceImpl singleton.
-  static CdmServiceImpl* GetInstance();
-
-  // CdmService implementation.
-  void Init() override;
-  void RegisterCdm(const CdmInfo& info) override;
-  const std::vector<CdmInfo>& GetAllRegisteredCdms() override;
-
- private:
-  friend struct base::DefaultLazyInstanceTraits<CdmServiceImpl>;
-  friend class CdmServiceImplTest;
-
-  CdmServiceImpl();
-  ~CdmServiceImpl() override;
-
-  std::vector<CdmInfo> cdms_;
-
-  DISALLOW_COPY_AND_ASSIGN(CdmServiceImpl);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_BROWSER_MEDIA_CDM_SERVICE_IMPL_H_
diff --git a/content/public/browser/BUILD.gn b/content/public/browser/BUILD.gn
index 5f8495e..bde6e84c 100644
--- a/content/public/browser/BUILD.gn
+++ b/content/public/browser/BUILD.gn
@@ -73,6 +73,7 @@
     "browser_url_handler.h",
     "cache_storage_context.h",
     "cache_storage_usage_info.h",
+    "cdm_registry.h",
     "certificate_request_result_type.h",
     "child_process_data.h",
     "child_process_security_policy.h",
diff --git a/content/public/browser/cdm_service.h b/content/public/browser/cdm_registry.h
similarity index 79%
rename from content/public/browser/cdm_service.h
rename to content/public/browser/cdm_registry.h
index 58d59e07..242331f 100644
--- a/content/public/browser/cdm_service.h
+++ b/content/public/browser/cdm_registry.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_PUBLIC_BROWSER_CDM_SERVICE_H_
-#define CONTENT_PUBLIC_BROWSER_CDM_SERVICE_H_
+#ifndef CONTENT_PUBLIC_BROWSER_CDM_REGISTRY_H_
+#define CONTENT_PUBLIC_BROWSER_CDM_REGISTRY_H_
 
 #include <vector>
 
@@ -14,12 +14,12 @@
 struct CdmInfo;
 
 // Keeps track of the Content Decryption Modules that are available.
-class CONTENT_EXPORT CdmService {
+class CONTENT_EXPORT CdmRegistry {
  public:
-  // Returns the CdmService singleton.
-  static CdmService* GetInstance();
+  // Returns the CdmRegistry singleton.
+  static CdmRegistry* GetInstance();
 
-  virtual ~CdmService() {}
+  virtual ~CdmRegistry() {}
 
   // Must be called on the instance to finish initialization.
   virtual void Init() = 0;
@@ -39,4 +39,4 @@
 
 }  // namespace content
 
-#endif  // CONTENT_PUBLIC_BROWSER_CDM_SERVICE_H_
+#endif  // CONTENT_PUBLIC_BROWSER_CDM_REGISTRY_H_
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index d63d0f6..d6ce9b5f 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -1121,7 +1121,7 @@
     "../browser/media/capture/cursor_renderer_aura_unittest.cc",
     "../browser/media/capture/web_contents_audio_input_stream_unittest.cc",
     "../browser/media/capture/web_contents_video_capture_device_unittest.cc",
-    "../browser/media/cdm_service_impl_unittest.cc",
+    "../browser/media/cdm_registry_impl_unittest.cc",
     "../browser/media/media_internals_unittest.cc",
     "../browser/media/midi_host_unittest.cc",
     "../browser/media/session/audio_focus_manager_unittest.cc",
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd
index bee35d9e..77560a5 100644
--- a/ios/chrome/app/strings/ios_strings.grd
+++ b/ios/chrome/app/strings/ios_strings.grd
@@ -1038,6 +1038,9 @@
       <message name="IDS_IOS_QR_SCANNER_VIEWPORT_CAPTION" desc="Message displayed below the QR scanner viewport instructing the user to position the scanned QR or bar code inside the viewport. [Length: unlimited] [iOS only]">
         QR Code or barcode
       </message>
+      <message name="IDS_IOS_READING_LIST_SNACKBAR_MESSAGE" desc="Message briefly displayed at the bottom of the screen to the user to inform that the selected page has been added to the reading list. [Length: 35em]" meaning="The selected page has been added to your reading list. [Length: 35em]">
+        Added to Reading List
+      </message>
       <message name="IDS_IOS_READING_LIST_CANCEL_BUTTON" desc="Label of the button to stop editing the reading list entries (delete, mark as read/unread) [Length: 15em]" meaning="Stop editing. [Length: 15em]">
         Cancel
       </message>
diff --git a/ios/chrome/browser/about_flags.mm b/ios/chrome/browser/about_flags.mm
index 4fbfd94f..c810392 100644
--- a/ios/chrome/browser/about_flags.mm
+++ b/ios/chrome/browser/about_flags.mm
@@ -234,13 +234,6 @@
     command_line->AppendSwitch(switches::kDisablePaymentRequest);
   }
 
-  // Populate command line flags from Reading List.
-  if ([defaults boolForKey:@"EnableReadingList"]) {
-    command_line->AppendSwitch(reading_list::switches::kEnableReadingList);
-  } else {
-    command_line->AppendSwitch(reading_list::switches::kDisableReadingList);
-  }
-
   // Populate command line flag for Spotlight Actions.
   if ([defaults boolForKey:@"DisableSpotlightActions"]) {
     command_line->AppendSwitch(switches::kDisableSpotlightActions);
diff --git a/ios/chrome/browser/reading_list/reading_list_web_state_observer.h b/ios/chrome/browser/reading_list/reading_list_web_state_observer.h
index c92dddb0..47fcfb6f 100644
--- a/ios/chrome/browser/reading_list/reading_list_web_state_observer.h
+++ b/ios/chrome/browser/reading_list/reading_list_web_state_observer.h
@@ -54,6 +54,7 @@
   ReadingListModel* reading_list_model_;
   std::unique_ptr<base::Timer> timer_;
   GURL pending_url_;
+  int try_number_;
 
   DISALLOW_COPY_AND_ASSIGN(ReadingListWebStateObserver);
 };
diff --git a/ios/chrome/browser/reading_list/reading_list_web_state_observer.mm b/ios/chrome/browser/reading_list/reading_list_web_state_observer.mm
index c2dc319..b4aa9c09 100644
--- a/ios/chrome/browser/reading_list/reading_list_web_state_observer.mm
+++ b/ios/chrome/browser/reading_list/reading_list_web_state_observer.mm
@@ -104,6 +104,7 @@
 void ReadingListWebStateObserver::StartCheckingProgress(
     const GURL& pending_url) {
   pending_url_ = pending_url;
+  try_number_ = 0;
   timer_.reset(new base::Timer(false, true));
   const base::TimeDelta kDelayUntilLoadingProgressIsChecked =
       base::TimeDelta::FromSeconds(1);
@@ -128,10 +129,15 @@
   if (!entry || entry->DistilledState() != ReadingListEntry::PROCESSED) {
     return;
   }
+  try_number_++;
   double progress = web_state()->GetLoadingProgress();
-  const double kMinimumExpectedProgress = 0.15;
-  if (progress < kMinimumExpectedProgress) {
+  const double kMinimumExpectedProgressPerStep = 0.25;
+  if (progress < try_number_ * kMinimumExpectedProgressPerStep) {
     reading_list::LoadReadingListDistilled(*entry, reading_list_model_,
                                            web_state());
   }
+  if (try_number_ >= 3) {
+    // Loading reached 75%, let the page finish normal loading.
+    timer_->Stop();
+  }
 }
diff --git a/ios/chrome/browser/sync/BUILD.gn b/ios/chrome/browser/sync/BUILD.gn
index 6886866..7711e27 100644
--- a/ios/chrome/browser/sync/BUILD.gn
+++ b/ios/chrome/browser/sync/BUILD.gn
@@ -112,6 +112,7 @@
     ":sync",
     "//base",
     "//components/browser_sync",
+    "//components/reading_list/core",
     "//components/sync",
     "//ios/chrome/browser/browser_state:test_support",
     "//ios/web:test_support",
diff --git a/ios/chrome/browser/sync/ios_chrome_profile_sync_service_factory_unittest.cc b/ios/chrome/browser/sync/ios_chrome_profile_sync_service_factory_unittest.cc
index 6bb725a..a6514e3b 100644
--- a/ios/chrome/browser/sync/ios_chrome_profile_sync_service_factory_unittest.cc
+++ b/ios/chrome/browser/sync/ios_chrome_profile_sync_service_factory_unittest.cc
@@ -12,6 +12,7 @@
 #include "base/macros.h"
 #include "components/browser_sync/browser_sync_switches.h"
 #include "components/browser_sync/profile_sync_service.h"
+#include "components/reading_list/core/reading_list_switches.h"
 #include "components/sync/base/model_type.h"
 #include "components/sync/driver/data_type_controller.h"
 #include "ios/chrome/browser/browser_state/test_chrome_browser_state.h"
@@ -45,6 +46,9 @@
     datatypes.push_back(syncer::PASSWORDS);
     datatypes.push_back(syncer::PREFERENCES);
     datatypes.push_back(syncer::PRIORITY_PREFERENCES);
+    if (reading_list::switches::IsReadingListEnabled()) {
+      datatypes.push_back(syncer::READING_LIST);
+    }
     datatypes.push_back(syncer::SESSIONS);
     datatypes.push_back(syncer::PROXY_TABS);
     datatypes.push_back(syncer::TYPED_URLS);
diff --git a/services/service_manager/runner/host/child_process_host.cc b/services/service_manager/runner/host/child_process_host.cc
index faf2ba58..ddbf2c0f 100644
--- a/services/service_manager/runner/host/child_process_host.cc
+++ b/services/service_manager/runner/host/child_process_host.cc
@@ -11,6 +11,7 @@
 #include "base/base_paths.h"
 #include "base/bind.h"
 #include "base/command_line.h"
+#include "base/files/file_path.h"
 #include "base/location.h"
 #include "base/logging.h"
 #include "base/macros.h"
@@ -41,6 +42,28 @@
 #include "services/service_manager/public/cpp/standalone_service/mach_broker.h"
 #endif
 
+#if defined(OS_WIN) && defined(COMPONENT_BUILD)
+#include <windows.h>
+
+namespace {
+
+class ScopedDllDirectoryOverride {
+ public:
+  explicit ScopedDllDirectoryOverride(const base::FilePath& path) {
+    SetDllDirectory(path.value().c_str());
+  }
+
+  ~ScopedDllDirectoryOverride() {
+    SetDllDirectory(NULL);
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ScopedDllDirectoryOverride);
+};
+
+}  // namespace
+#endif  // defined(OS_WIN) && defined(COMPONENT_BUILD)
+
 namespace service_manager {
 
 ChildProcessHost::ChildProcessHost(base::TaskRunner* launch_process_runner,
@@ -205,6 +228,8 @@
 #if defined(OS_MACOSX)
     MachBroker* mach_broker = MachBroker::GetInstance();
     base::AutoLock locker(mach_broker->GetLock());
+#elif defined(OS_WIN) && defined(COMPONENT_BUILD)
+    ScopedDllDirectoryOverride dll_override(exe_dir);
 #endif
     child_process_ = base::LaunchProcess(*child_command_line, options);
 #if defined(OS_MACOSX)
diff --git a/third_party/WebKit/LayoutTests/fast/dom/geometry-interfaces-dom-matrix-readonly.html b/third_party/WebKit/LayoutTests/fast/dom/geometry-interfaces-dom-matrix-readonly.html
index 49f861b..72c1c8fb 100644
--- a/third_party/WebKit/LayoutTests/fast/dom/geometry-interfaces-dom-matrix-readonly.html
+++ b/third_party/WebKit/LayoutTests/fast/dom/geometry-interfaces-dom-matrix-readonly.html
@@ -46,6 +46,20 @@
 }, "DOMMatrixReadOnly fromFloat64Array - 3D matrix");
 
 test(() => {
+  var matrix = new DOMMatrixReadOnly("");
+  assert_identity_2d_matrix(matrix);
+}, "DOMMatrixReadOnly(transformList) - emptyString");
+
+test(() => {
+  var matrix = new DOMMatrixReadOnly("matrix(1.0, 2.0, 3.0, 4.0, 5.0, 6.0) translate(44px, 55px) skewX(30deg)");
+  var expectedMatrix = new DOMMatrixReadOnly();
+  expectedMatrix = expectedMatrix.multiply(new DOMMatrixReadOnly([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]))
+  expectedMatrix = expectedMatrix.translate(44, 55)
+  expectedMatrix = expectedMatrix.skewX(30);
+  assert_matrix_almost_equals(matrix, expectedMatrix);
+}, "DOMMatrixReadOnly(transformList) - transformList");
+
+test(() => {
   var matrix2d = new DOMMatrixReadOnly([1, 2, 3, 3.1, 2, 1]);
   assert_true(matrix2d.is2D);
   assert_equals(matrix2d.toString(), "matrix(1, 2, 3, 3.1, 2, 1)");
@@ -94,85 +108,109 @@
 }, "DOMMatrixReadOnly toJSON() - 3D matrix");
 
 test(() => {
-  assert_throws(new TypeError(), () => { new DOMMatrixReadOnly(1, 2, 3, 4, 5, 6); },
-    "DOMMatrixReadOnly constructor only accepts 1 argument");
-  assert_throws(new TypeError(), () => { new DOMMatrixReadOnly("myString"); },
-    "DOMMatrixReadOnly constructor only accepts 1 number sequence");
+  assert_throws(new SyntaxError(), () => { new DOMMatrixReadOnly(1, 2, 3, 4, 5, 6); },
+    "DOMMatrixReadOnly(transformList) can't parse unknown keyword - DOMMatrixReadOnly(1, 2, 3, 4, 5, 6) is same with DOMMatrixReadOnly('1')");
+  assert_throws(new SyntaxError(), () => { new DOMMatrixReadOnly("myString"); },
+    "DOMMatrixReadOnly(transformList) can't parse unknown keyword");
+  assert_throws(new SyntaxError(), () => { new DOMMatrixReadOnly("initial");},
+    "CSS-wide keywords are disallowed");
+  assert_throws(new SyntaxError(), () => { new DOMMatrixReadOnly("notExistFunction()"); },
+    "can't parse not exist function");
+  assert_throws(new SyntaxError(), () => { new DOMMatrixReadOnly("translateY(50%)"); },
+    "using relative units should throw a SyntaxError");
+  assert_throws(new SyntaxError(), () => { new DOMMatrixReadOnly("translateX(1.2em)"); },
+    "using relative units should throw a SyntaxError");
+  assert_throws(new SyntaxError(), () => { new DOMMatrixReadOnly("translateX(10ex)"); },
+    "using relative units should throw a SyntaxError");
+  assert_throws(new SyntaxError(), () => { new DOMMatrixReadOnly("translateX(10ch)"); },
+    "using relative units should throw a SyntaxError");
+  assert_throws(new SyntaxError(), () => { new DOMMatrixReadOnly("translateX(10rem)"); },
+    "using relative units should throw a SyntaxError");
+  assert_throws(new SyntaxError(), () => { new DOMMatrixReadOnly("translateX(10vw)"); },
+    "using relative units should throw a SyntaxError");
+  assert_throws(new SyntaxError(), () => { new DOMMatrixReadOnly("translateX(10vh)"); },
+    "using relative units should throw a SyntaxError");
+  assert_throws(new SyntaxError(), () => { new DOMMatrixReadOnly("translateX(10vmin)"); },
+    "using relative units should throw a SyntaxError");
+  assert_throws(new SyntaxError(), () => { new DOMMatrixReadOnly("translateX(10vmax)"); },
+    "using relative units should throw a SyntaxError");
+  assert_throws(new SyntaxError(), () => { new DOMMatrixReadOnly("translateX(calc(10px + 1em))"); },
+    "using relative units should throw a SyntaxError");
   assert_throws(new TypeError(), () => { new DOMMatrixReadOnly([1, 2, 3]); },
-    "DOMMatrixReadOnly constructor only accepts 1 number sequence with 6 or 16 elements.");
+    "DOMMatrixReadOnly constructor only accepts 1 number sequence with 6 or 16 elements");
 }, "DOMMatrixReadOnly constructor - invalid arguments");
 
 test(() => {
   assert_throws(new TypeError(), () => { DOMMatrixReadOnly.fromFloat32Array(new Float32Array([1, 2, 3, 4, 5])); },
-    "fromFloat32Array function only accepts 1 Float32Array with 6 or 16 elements.");
+    "fromFloat32Array function only accepts 1 Float32Array with 6 or 16 elements");
   assert_throws(new TypeError(), () => { DOMMatrixReadOnly.fromFloat64Array(new Float64Array([1, 2, 3, 4, 5])); },
-    "fromFloat64Array function only accepts 1 Float64Array with 6 or 16 elements.");
+    "fromFloat64Array function only accepts 1 Float64Array with 6 or 16 elements");
   assert_throws(new TypeError(), () => { DOMMatrixReadOnly.fromFloat32Array(new Float32Array([1, 2, 3, 4, 5, 6 ,7])); },
-    "fromFloat32Array function only accepts 1 Float32Array with 6 or 16 elements.");
+    "fromFloat32Array function only accepts 1 Float32Array with 6 or 16 elements");
   assert_throws(new TypeError(), () => { DOMMatrixReadOnly.fromFloat64Array(new Float64Array([1, 2, 3, 4, 5, 6 ,7])); },
-    "fromFloat64Array function only accepts 1 Float64Array with 6 or 16 elements.");
+    "fromFloat64Array function only accepts 1 Float64Array with 6 or 16 elements");
 }, "DOMMatrixReadOnly fromFloat*Array - invalid array size of nearby 6");
 
 test(() => {
   assert_throws(new TypeError(), () => { DOMMatrixReadOnly.fromFloat32Array(new Float32Array([1, 2, 3, 4, 5, 6 ,7, 8, 9, 10, 11, 12, 13, 14, 15])); },
-    "fromFloat32Array function only accepts 1 Float32Array with 6 or 16 elements.");
+    "fromFloat32Array function only accepts 1 Float32Array with 6 or 16 elements");
   assert_throws(new TypeError(), () => { DOMMatrixReadOnly.fromFloat64Array(new Float64Array([1, 2, 3, 4, 5, 6 ,7, 8, 9, 10, 11, 12, 13, 14, 15])); },
-    "fromFloat64Array function only accepts 1 Float64Array with 6 or 16 elements.");
+    "fromFloat64Array function only accepts 1 Float64Array with 6 or 16 elements");
   assert_throws(new TypeError(), () => { DOMMatrixReadOnly.fromFloat32Array(new Float32Array([1, 2, 3, 4, 5, 6 ,7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17])); },
-    "fromFloat32Array function only accepts 1 Float32Array with 6 or 16 elements.");
+    "fromFloat32Array function only accepts 1 Float32Array with 6 or 16 elements");
   assert_throws(new TypeError(), () => { DOMMatrixReadOnly.fromFloat64Array(new Float64Array([1, 2, 3, 4, 5, 6 ,7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17])); },
-    "fromFloat64Array function only accepts 1 Float64Array with 6 or 16 elements.");
+    "fromFloat64Array function only accepts 1 Float64Array with 6 or 16 elements");
 }, "DOMMatrixReadOnly fromFloat*Array - invalid array size of nearby 16");
 
 test(() => {
   assert_throws(new TypeError(), () => { DOMMatrixReadOnly.fromFloat32Array(new Float32Array([])); },
-    "fromFloat32Array function only accepts 1 Float32Array with 6 or 16 elements.");
+    "fromFloat32Array function only accepts 1 Float32Array with 6 or 16 elements");
   assert_throws(new TypeError(), () => { DOMMatrixReadOnly.fromFloat64Array(new Float64Array([])); },
-    "fromFloat64Array function only accepts 1 Float64Array with 6 or 16 elements.");
+    "fromFloat64Array function only accepts 1 Float64Array with 6 or 16 elements");
   assert_throws(new TypeError(), () => { DOMMatrixReadOnly.fromFloat32Array(new Float32Array([1])); },
-    "fromFloat32Array function only accepts 1 Float32Array with 6 or 16 elements.");
+    "fromFloat32Array function only accepts 1 Float32Array with 6 or 16 elements");
   assert_throws(new TypeError(), () => { DOMMatrixReadOnly.fromFloat64Array(new Float64Array([1])); },
-    "fromFloat64Array function only accepts 1 Float64Array with 6 or 16 elements.");
+    "fromFloat64Array function only accepts 1 Float64Array with 6 or 16 elements");
   assert_throws(new TypeError(), () => { DOMMatrixReadOnly.fromFloat32Array(new Float32Array(65536)); },
-    "fromFloat32Array function only accepts 1 Float32Array with 6 or 16 elements.");
+    "fromFloat32Array function only accepts 1 Float32Array with 6 or 16 elements");
   assert_throws(new TypeError(), () => { DOMMatrixReadOnly.fromFloat64Array(new Float64Array(65536)); },
-    "fromFloat64Array function only accepts 1 Float64Array with 6 or 16 elements.");
+    "fromFloat64Array function only accepts 1 Float64Array with 6 or 16 elements");
 }, "DOMMatrixReadOnly fromFloat*Array - invalid array size");
 
 test(() => {
   var matrix = DOMMatrixReadOnly.fromMatrix();
   assert_identity_2d_matrix(matrix);
-}, "DOMMatrixReadOnly.fromMatrix() with no parameter.");
+}, "DOMMatrixReadOnly.fromMatrix() with no parameter");
 
 test(() => {
   var matrix = DOMMatrixReadOnly.fromMatrix(null);
   assert_identity_2d_matrix(matrix);
-}, "DOMMatrixReadOnly.fromMatrix() with null.");
+}, "DOMMatrixReadOnly.fromMatrix() with null");
 
 test(() => {
   var matrix = DOMMatrixReadOnly.fromMatrix(undefined);
   assert_identity_2d_matrix(matrix);
-}, "DOMMatrixReadOnly.fromMatrix() with undefined.");
+}, "DOMMatrixReadOnly.fromMatrix() with undefined");
 
 test(() => {
   var matrix = DOMMatrixReadOnly.fromMatrix({});
   assert_identity_2d_matrix(matrix);
-}, "DOMMatrixReadOnly.fromMatrix() with empty object.");
+}, "DOMMatrixReadOnly.fromMatrix() with empty object");
 
 test(() => {
   var matrix = DOMMatrixReadOnly.fromMatrix({a: 1, b: 2, c: 3, d: 4, e: 5, f: 6});
   assert_2d_matrix_equals(matrix, [1, 2, 3, 4, 5, 6]);
-}, "DOMMatrixReadOnly.fromMatrix({a: 1, b: 2, c: 3, d: 4, e: 5, f: 6}) should create a 2D DOMMatrixReadOnly.");
+}, "DOMMatrixReadOnly.fromMatrix({a: 1, b: 2, c: 3, d: 4, e: 5, f: 6}) should create a 2D DOMMatrixReadOnly");
 
 test(() => {
   var matrix = DOMMatrixReadOnly.fromMatrix({m11: 1, m22: 2, m33: 3, m44: 4, m23: 5, m43: 6});
   assert_3d_matrix_equals(matrix, [1, 0, 0, 0, 0, 2, 5, 0, 0, 0, 3, 0, 0, 0, 6, 4]);
-}, "DOMMatrixReadOnly.fromMatrix({m11: 1, m22: 2, m33: 3, m44: 4, m23: 5, m43: 6}) should create a 3D DOMMatrixReadOnly.");
+}, "DOMMatrixReadOnly.fromMatrix({m11: 1, m22: 2, m33: 3, m44: 4, m23: 5, m43: 6}) should create a 3D DOMMatrixReadOnly");
 
 test(() => {
   var matrix = DOMMatrixReadOnly.fromMatrix({a: 7, c: 9});
   assert_2d_matrix_equals(matrix, [7, 0, 9, 1, 0, 0]);
-}, "If 2d related properties don't be set, should set to fallback.");
+}, "If 2d related properties don't be set, should set to fallback");
 
 test(() => {
   var matrix = DOMMatrixReadOnly.fromMatrix({
@@ -188,10 +226,10 @@
 test(() => {
   assert_throws(new TypeError(), () => {
     DOMMatrixReadOnly.fromMatrix({a: 1, b: 2, m33: 3, m44: 4, is2D: true});
-  }, "The 'is2D' property is set to true but the input matrix is 3d matrix.");
+  }, "The 'is2D' property is set to true but the input matrix is 3d matrix");
   assert_throws(new TypeError(), () => {
     DOMMatrixReadOnly.fromMatrix({a: 1, b: 2, m11: 3});
-  }, "The 'a' property should equal the 'm11' property.");
-}, "DOMMatrixReadOnly.fromMatrix(): Exception test.");
+  }, "The 'a' property should equal the 'm11' property");
+}, "DOMMatrixReadOnly.fromMatrix(): Exception test");
 
 </script>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/geometry-interfaces-dom-matrix-setMatrixValue.html b/third_party/WebKit/LayoutTests/fast/dom/geometry-interfaces-dom-matrix-setMatrixValue.html
index 8aa4e18..b4f837ab6 100644
--- a/third_party/WebKit/LayoutTests/fast/dom/geometry-interfaces-dom-matrix-setMatrixValue.html
+++ b/third_party/WebKit/LayoutTests/fast/dom/geometry-interfaces-dom-matrix-setMatrixValue.html
@@ -238,56 +238,56 @@
 
   assert_throws(new SyntaxError(), () => {
     actualMatrix.setMatrixValue("initial");
-  }, "CSS-wide keywords are disallowed.");
+  }, "CSS-wide keywords are disallowed");
 
   assert_throws(new SyntaxError(), () => {
     actualMatrix.setMatrixValue("notExistFunction()");
-  }, "can't parse not exist function.");
+  }, "can't parse not exist function");
 
   assert_throws(new SyntaxError(), () => {
     actualMatrix.setMatrixValue("translateY(50%)");
-  }, "Can't parse without absolute unit.");
+  }, "using relative units should throw a SyntaxError");
 
   assert_throws(new SyntaxError(), () => {
     actualMatrix.setMatrixValue("translateX(1.2em)");
-  }, "Can't parse without absolute unit.");
+  }, "using relative units should throw a SyntaxError");
 
   assert_throws(new SyntaxError(), () => {
     actualMatrix.setMatrixValue("translateX(10ex)");
-  }, "Can't parse without absolute unit.");
+  }, "using relative units should throw a SyntaxError");
 
   assert_throws(new SyntaxError(), () => {
     actualMatrix.setMatrixValue("translateX(10ch)");
-  }, "Can't parse without absolute unit.");
+  }, "using relative units should throw a SyntaxError");
 
   assert_throws(new SyntaxError(), () => {
     actualMatrix.setMatrixValue("translateX(10rem)");
-  }, "Can't parse without absolute unit.");
+  }, "using relative units should throw a SyntaxError");
 
   assert_throws(new SyntaxError(), () => {
     actualMatrix.setMatrixValue("translateX(10vw)");
-  }, "Can't parse without absolute unit.");
+  }, "using relative units should throw a SyntaxError");
 
   assert_throws(new SyntaxError(), () => {
     actualMatrix.setMatrixValue("translateX(10vh)");
-  }, "Can't parse without absolute unit.");
+  }, "using relative units should throw a SyntaxError");
 
   assert_throws(new SyntaxError(), () => {
     actualMatrix.setMatrixValue("translateX(10vmin)");
-  }, "Can't parse without absolute unit.");
+  }, "using relative units should throw a SyntaxError");
 
   assert_throws(new SyntaxError(), () => {
     actualMatrix.setMatrixValue("translateX(10vmax)");
-  }, "Can't parse without absolute unit.");
+  }, "using relative units should throw a SyntaxError");
 
   assert_throws(new SyntaxError(), () => {
     actualMatrix.setMatrixValue("translateX(calc(10px + 1em))");
-  }, "Can't parse without absolute unit.");
+  }, "using relative units should throw a SyntaxError");
 
   //actualMatrix should be not changed.
   assert_true(actualMatrix.is2D);
   assert_matrix_almost_equals(actualMatrix, expectedMatrix);
 
-}, "DOMMatrix.setMatrix(): Exception test.");
+}, "DOMMatrix.setMatrix(): Exception test");
 
 </script>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/geometry-interfaces-dom-matrix.html b/third_party/WebKit/LayoutTests/fast/dom/geometry-interfaces-dom-matrix.html
index ee37c50..998c3da 100644
--- a/third_party/WebKit/LayoutTests/fast/dom/geometry-interfaces-dom-matrix.html
+++ b/third_party/WebKit/LayoutTests/fast/dom/geometry-interfaces-dom-matrix.html
@@ -35,6 +35,20 @@
 }, "DOMMatrix fromFloat64Array - 3D matrix");
 
 test(() => {
+  var matrix = new DOMMatrix("");
+  assert_identity_2d_matrix(matrix);
+}, "DOMMatrix(transformList) - emptyString");
+
+test(() => {
+  var matrix = new DOMMatrix("matrix(1.0, 2.0, 3.0, 4.0, 5.0, 6.0) translate(44px, 55px) skewX(30deg)");
+  var expectedMatrix = new DOMMatrix();
+  expectedMatrix.multiplySelf(new DOMMatrix([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]))
+  expectedMatrix.translateSelf(44, 55)
+  expectedMatrix.skewXSelf(30);
+  assert_matrix_almost_equals(matrix, expectedMatrix);
+}, "DOMMatrix(transformList) - transformList");
+
+test(() => {
   var matrix = new DOMMatrix([1, 2, 3, 4, 5, 6]);
   assert_2d_matrix_equals(matrix, [1, 2, 3, 4, 5, 6]);
 }, "DOMMatrix(numberSequence) constructor");
@@ -67,75 +81,75 @@
   matrix.m33 = 1;
   assert_false(matrix.is2D);
   assert_true(matrix.isIdentity);
-}, "DOMMatrix.is2D can never be set to 'true' when it was set to 'false' before calling setMatrixValue().");
+}, "DOMMatrix.is2D can never be set to 'true' when it was set to 'false' before calling setMatrixValue()");
 
 test(() => {
   assert_throws(new TypeError(), () => { DOMMatrix.fromFloat32Array(new Float32Array([1, 2, 3, 4, 5])); },
-    "fromFloat32Array function only accepts 1 Float32Array with 6 or 16 elements.");
+    "fromFloat32Array function only accepts 1 Float32Array with 6 or 16 elements");
   assert_throws(new TypeError(), () => { DOMMatrix.fromFloat64Array(new Float64Array([1, 2, 3, 4, 5])); },
-    "fromFloat64Array function only accepts 1 Float64Array with 6 or 16 elements.");
+    "fromFloat64Array function only accepts 1 Float64Array with 6 or 16 elements");
   assert_throws(new TypeError(), () => { DOMMatrix.fromFloat32Array(new Float32Array([1, 2, 3, 4, 5, 6 ,7])); },
-    "fromFloat32Array function only accepts 1 Float32Array with 6 or 16 elements.");
+    "fromFloat32Array function only accepts 1 Float32Array with 6 or 16 elements");
   assert_throws(new TypeError(), () => { DOMMatrix.fromFloat64Array(new Float64Array([1, 2, 3, 4, 5, 6 ,7])); },
-    "fromFloat64Array function only accepts 1 Float64Array with 6 or 16 elements.");
+    "fromFloat64Array function only accepts 1 Float64Array with 6 or 16 elements");
 }, "DOMMatrix fromFloat*Array - invalid array size of nearby 6");
 
 test(() => {
   assert_throws(new TypeError(), () => { DOMMatrix.fromFloat32Array(new Float32Array([1, 2, 3, 4, 5, 6 ,7, 8, 9, 10, 11, 12, 13, 14, 15])); },
-    "fromFloat32Array function only accepts 1 Float32Array with 6 or 16 elements.");
+    "fromFloat32Array function only accepts 1 Float32Array with 6 or 16 elements");
   assert_throws(new TypeError(), () => { DOMMatrix.fromFloat64Array(new Float64Array([1, 2, 3, 4, 5, 6 ,7, 8, 9, 10, 11, 12, 13, 14, 15])); },
-    "fromFloat64Array function only accepts 1 Float64Array with 6 or 16 elements.");
+    "fromFloat64Array function only accepts 1 Float64Array with 6 or 16 elements");
   assert_throws(new TypeError(), () => { DOMMatrix.fromFloat32Array(new Float32Array([1, 2, 3, 4, 5, 6 ,7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17])); },
-    "fromFloat32Array function only accepts 1 Float32Array with 6 or 16 elements.");
+    "fromFloat32Array function only accepts 1 Float32Array with 6 or 16 elements");
   assert_throws(new TypeError(), () => { DOMMatrix.fromFloat64Array(new Float64Array([1, 2, 3, 4, 5, 6 ,7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17])); },
-    "fromFloat64Array function only accepts 1 Float64Array with 6 or 16 elements.");
+    "fromFloat64Array function only accepts 1 Float64Array with 6 or 16 elements");
 }, "DOMMatrix fromFloat*Array - invalid array size of nearby 16");
 
 test(() => {
   assert_throws(new TypeError(), () => { DOMMatrix.fromFloat32Array(new Float32Array([])); },
-    "fromFloat32Array function only accepts 1 Float32Array with 6 or 16 elements.");
+    "fromFloat32Array function only accepts 1 Float32Array with 6 or 16 elements");
   assert_throws(new TypeError(), () => { DOMMatrix.fromFloat64Array(new Float64Array([])); },
-    "fromFloat64Array function only accepts 1 Float64Array with 6 or 16 elements.");
+    "fromFloat64Array function only accepts 1 Float64Array with 6 or 16 elements");
   assert_throws(new TypeError(), () => { DOMMatrix.fromFloat32Array(new Float32Array([1])); },
-    "fromFloat32Array function only accepts 1 Float32Array with 6 or 16 elements.");
+    "fromFloat32Array function only accepts 1 Float32Array with 6 or 16 elements");
   assert_throws(new TypeError(), () => { DOMMatrix.fromFloat64Array(new Float64Array([1])); },
-    "fromFloat64Array function only accepts 1 Float64Array with 6 or 16 elements.");
+    "fromFloat64Array function only accepts 1 Float64Array with 6 or 16 elements");
   assert_throws(new TypeError(), () => { DOMMatrix.fromFloat32Array(new Float32Array(65536)); },
-    "fromFloat32Array function only accepts 1 Float32Array with 6 or 16 elements.");
+    "fromFloat32Array function only accepts 1 Float32Array with 6 or 16 elements");
   assert_throws(new TypeError(), () => { DOMMatrix.fromFloat64Array(new Float64Array(65536)); },
-    "fromFloat64Array function only accepts 1 Float64Array with 6 or 16 elements.");
+    "fromFloat64Array function only accepts 1 Float64Array with 6 or 16 elements");
 }, "DOMMatrix fromFloat*Array - invalid array size");
 
 test(() => {
   assert_identity_2d_matrix(DOMMatrix.fromMatrix());
-}, "DOMMatrix.fromMatrix() with no parameter.");
+}, "DOMMatrix.fromMatrix() with no parameter");
 
 test(() => {
   assert_identity_2d_matrix(DOMMatrix.fromMatrix(null));
-}, "DOMMatrix.fromMatrix() with null.");
+}, "DOMMatrix.fromMatrix() with null");
 
 test(() => {
   assert_identity_2d_matrix(DOMMatrix.fromMatrix(undefined));
-}, "DOMMatrix.fromMatrix() with undefined.");
+}, "DOMMatrix.fromMatrix() with undefined");
 
 test(() => {
   assert_identity_2d_matrix(DOMMatrix.fromMatrix({}));
-}, "DOMMatrix.fromMatrix() with empty object.");
+}, "DOMMatrix.fromMatrix() with empty object");
 
 test(() => {
   var matrix = DOMMatrix.fromMatrix({a: 1, b: 2, c: 3, d: 4, e: 5, f: 6});
   assert_2d_matrix_equals(matrix, [1, 2, 3, 4, 5, 6]);
-}, "DOMMatrix.fromMatrix({a: 1, b: 2, c: 3, d: 4, e: 5, f: 6}) should create a 2D DOMMatrix.");
+}, "DOMMatrix.fromMatrix({a: 1, b: 2, c: 3, d: 4, e: 5, f: 6}) should create a 2D DOMMatrix");
 
 test(() => {
   var matrix = DOMMatrix.fromMatrix({m11: 1, m22: 2, m33: 3, m44: 4, m23: 5, m43: 6});
   assert_3d_matrix_equals(matrix, [1, 0, 0, 0, 0, 2, 5, 0, 0, 0, 3, 0, 0, 0, 6, 4]);
-}, "DOMMatrix.fromMatrix({m11: 1, m22: 2, m33: 3, m44: 4, m23: 5, m43: 6}) should create a 3D DOMMatrix.");
+}, "DOMMatrix.fromMatrix({m11: 1, m22: 2, m33: 3, m44: 4, m23: 5, m43: 6}) should create a 3D DOMMatrix");
 
 test(() => {
   var matrix = DOMMatrix.fromMatrix({a: 7, c: 9});
   assert_2d_matrix_equals(matrix, [7, 0, 9, 1, 0, 0]);
-}, "If 2d related properties don't be set, should set to fallback.");
+}, "If 2d related properties don't be set, should set to fallback");
 
 test(() => {
   var matrix = DOMMatrix.fromMatrix({
@@ -185,11 +199,40 @@
 }, "DOMMatrix toJSON() - 3D matrix");
 
 test(() => {
+  assert_throws(new SyntaxError(), () => { new DOMMatrix(1, 2, 3, 4, 5, 6); },
+    "DOMMatrix(transformList) can't parse unknown keyword - DOMMatrixReadOnly(1, 2, 3, 4, 5, 6) is same with DOMMatrixReadOnly('1')");
+  assert_throws(new SyntaxError(), () => { new DOMMatrix("myString"); },
+    "DOMMatrix(transformList) can't parse unknown keyword");
+  assert_throws(new SyntaxError(), () => { new DOMMatrix("initial");},
+    "CSS-wide keywords are disallowed");
+  assert_throws(new SyntaxError(), () => { new DOMMatrix("notExistFunction()"); },
+    "can't parse not exist function");
+  assert_throws(new SyntaxError(), () => { new DOMMatrix("translateY(50%)"); },
+    "using relative units should throw a SyntaxError");
+  assert_throws(new SyntaxError(), () => { new DOMMatrix("translateX(1.2em)"); },
+    "using relative units should throw a SyntaxError");
+  assert_throws(new SyntaxError(), () => { new DOMMatrix("translateX(10ex)"); },
+    "using relative units should throw a SyntaxError");
+  assert_throws(new SyntaxError(), () => { new DOMMatrix("translateX(10ch)"); },
+    "using relative units should throw a SyntaxError");
+  assert_throws(new SyntaxError(), () => { new DOMMatrix("translateX(10rem)"); },
+    "using relative units should throw a SyntaxError");
+  assert_throws(new SyntaxError(), () => { new DOMMatrix("translateX(10vw)"); },
+    "using relative units should throw a SyntaxError");
+  assert_throws(new SyntaxError(), () => { new DOMMatrix("translateX(10vh)"); },
+    "using relative units should throw a SyntaxError");
+  assert_throws(new SyntaxError(), () => { new DOMMatrix("translateX(10vmin)"); },
+    "using relative units should throw a SyntaxError");
+  assert_throws(new SyntaxError(), () => { new DOMMatrix("translateX(10vmax)"); },
+    "using relative units should throw a SyntaxError");
+  assert_throws(new SyntaxError(), () => { new DOMMatrix("translateX(calc(10px + 1em))"); },
+    "using relative units should throw a SyntaxError");
   assert_throws(new TypeError(), () => {
     var matrix = DOMMatrix.fromMatrix({a: 1, b: 2, m33: 3, m44: 4, is2D: true});
-  }, "The 'is2D' property is set to true but the input matrix is 3d matrix.");
+  }, "The 'is2D' property is set to true but the input matrix is 3d matrix");
   assert_throws(new TypeError(), () => {
     var matrix = DOMMatrix.fromMatrix({a: 1, b: 2, m11: 3});
-  }, "The 'a' property should equal the 'm11' property.");
-}, "DOMMatrix.fromMatrix(): Exception test.");
+  }, "The 'a' property should equal the 'm11' property");
+}, "DOMMatrix.fromMatrix(): Exception test");
+
 </script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/styles-do-not-add-inline-stylesheets-in-navigator-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/styles-do-not-add-inline-stylesheets-in-navigator-expected.txt
new file mode 100644
index 0000000..566feafd
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/styles-do-not-add-inline-stylesheets-in-navigator-expected.txt
@@ -0,0 +1,10 @@
+Verify that inline stylesheets do not appear in navigator.
+
+top
+  127.0.0.1:8000
+    inspector
+      elements/styles
+        styles-do-not-add-inline-stylesheets-in-navigator.html
+      elements-test.js
+      inspector-test.js
+
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/styles-do-not-add-inline-stylesheets-in-navigator.html b/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/styles-do-not-add-inline-stylesheets-in-navigator.html
new file mode 100644
index 0000000..6200e3b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector/elements/styles/styles-do-not-add-inline-stylesheets-in-navigator.html
@@ -0,0 +1,35 @@
+<html>
+<head>
+<script src="../../inspector-test.js"></script>
+<script src="../../elements-test.js"></script>
+<style>
+</style>
+<script>
+function injectStyleSheet()
+{
+    var style = document.createElement('style');
+    style.textContent = '* {color: blue; }';
+    document.head.appendChild(style);
+}
+
+function test()
+{
+    Promise.all([
+        UI.inspectorView.showPanel('sources'),
+        InspectorTest.evaluateInPagePromise('injectStyleSheet()')
+    ]).then(onInjected);
+
+    function onInjected()
+    {
+        var sourcesNavigator = new Sources.SourcesNavigatorView();
+        InspectorTest.dumpNavigatorView(sourcesNavigator);
+        InspectorTest.completeTest();
+    }
+}
+</script>
+</head>
+
+<body onload="runTest()">
+<p>Verify that inline stylesheets do not appear in navigator.</p>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/shadow-dom/crashes/focus-navigation-infinite-loop.html b/third_party/WebKit/LayoutTests/shadow-dom/crashes/focus-navigation-infinite-loop.html
new file mode 100644
index 0000000..31410db9
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/shadow-dom/crashes/focus-navigation-infinite-loop.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<script src='../../resources/testharness.js'></script>
+<script src='../../resources/testharnessreport.js'></script>
+<script src='../resources/shadow-dom.js'></script>
+<script src='../resources/focus-utils.js'></script>
+<body>
+  <input id="input-before">
+  <div id="host" tabindex="0">
+    <template>
+      <span>x-element</span>
+      <slot tabindex="1"></slot>
+    </template>                                                                  </div>
+  <input id="input-after">
+</body>
+<script>
+'use strict';
+
+test(() => {
+  let host = document.querySelector('#host');
+  convertTemplatesToShadowRootsWithin(host);
+  let elements = [
+    'input-before',
+    'host',
+    'input-after'
+  ];
+  assert_focus_navigation_forward(elements);
+  elements.reverse();
+  assert_focus_navigation_backward(elements);
+}, 'Focus navigation should not get stuck.');
+</script>
diff --git a/third_party/WebKit/Source/bindings/scripts/code_generator.py b/third_party/WebKit/Source/bindings/scripts/code_generator.py
index 2b66cea..ad78bd3 100644
--- a/third_party/WebKit/Source/bindings/scripts/code_generator.py
+++ b/third_party/WebKit/Source/bindings/scripts/code_generator.py
@@ -12,7 +12,6 @@
 import sys
 
 from idl_types import set_ancestors, IdlType
-from v8_attributes import attribute_filters
 from v8_globals import includes
 from v8_interface import constant_filters
 from v8_types import set_component_dirs
@@ -89,7 +88,6 @@
         'runtime_enabled': runtime_enabled_if,
         'secure_context': secure_context_if,
         'unique_by': unique_by})
-    jinja_env.filters.update(attribute_filters())
     jinja_env.filters.update(constant_filters())
     jinja_env.filters.update(method_filters())
     return jinja_env
diff --git a/third_party/WebKit/Source/bindings/scripts/v8_attributes.py b/third_party/WebKit/Source/bindings/scripts/v8_attributes.py
index b0e4194..715be5d8 100644
--- a/third_party/WebKit/Source/bindings/scripts/v8_attributes.py
+++ b/third_party/WebKit/Source/bindings/scripts/v8_attributes.py
@@ -228,7 +228,7 @@
     return context
 
 
-def filter_has_accessor_configuration(attributes):
+def filter_accessors(attributes):
     return [attribute for attribute in attributes if
             not (attribute['exposed_test'] or
                  attribute['secure_context_test'] or
@@ -238,26 +238,25 @@
             attribute['should_be_exposed_to_script']]
 
 
-def filter_has_data_attribute_configuration(attributes):
-    return [attribute for attribute in attributes if
-            not (attribute['exposed_test'] or
+def is_data_attribute(attribute):
+    return (not (attribute['exposed_test'] or
                  attribute['secure_context_test'] or
                  attribute['origin_trial_enabled_function'] or
                  attribute['runtime_enabled_function']) and
             attribute['is_data_type_property'] and
-            attribute['should_be_exposed_to_script']]
+            attribute['should_be_exposed_to_script'])
 
 
 def is_lazy_data_attribute(attribute):
     return attribute['constructor_type'] and not attribute['needs_constructor_getter_callback']
 
 
-def filter_has_attribute_configuration(attributes):
-    return [attribute for attribute in filter_has_data_attribute_configuration(attributes) if not is_lazy_data_attribute(attribute)]
+def filter_data_attributes(attributes):
+    return [attribute for attribute in attributes if is_data_attribute(attribute) and not is_lazy_data_attribute(attribute)]
 
 
-def filter_has_lazy_data_attribute_configuration(attributes):
-    return [attribute for attribute in filter_has_data_attribute_configuration(attributes) if is_lazy_data_attribute(attribute)]
+def filter_lazy_data_attributes(attributes):
+    return [attribute for attribute in attributes if is_data_attribute(attribute) and is_lazy_data_attribute(attribute)]
 
 
 def filter_origin_trial_enabled(attributes):
@@ -266,21 +265,13 @@
             not attribute['exposed_test']]
 
 
-def filter_purely_runtime_enabled(attributes):
+def filter_runtime_enabled(attributes):
     return [attribute for attribute in attributes if
             not (attribute['exposed_test'] or
                  attribute['secure_context_test']) and
             attribute['runtime_feature_name']]
 
 
-def attribute_filters():
-    return {'has_accessor_configuration': filter_has_accessor_configuration,
-            'has_attribute_configuration': filter_has_attribute_configuration,
-            'has_lazy_data_attribute_configuration': filter_has_lazy_data_attribute_configuration,
-            'origin_trial_enabled_attributes': filter_origin_trial_enabled,
-            'purely_runtime_enabled_attributes': filter_purely_runtime_enabled}
-
-
 ################################################################################
 # Getter
 ################################################################################
diff --git a/third_party/WebKit/Source/bindings/scripts/v8_interface.py b/third_party/WebKit/Source/bindings/scripts/v8_interface.py
index a9a7acf..1f7ab537 100644
--- a/third_party/WebKit/Source/bindings/scripts/v8_interface.py
+++ b/third_party/WebKit/Source/bindings/scripts/v8_interface.py
@@ -371,6 +371,12 @@
 
     context.update({
         'attributes': attributes,
+        # Elements in attributes are broken in following members.
+        'accessors': v8_attributes.filter_accessors(attributes),
+        'data_attributes': v8_attributes.filter_data_attributes(attributes),
+        'lazy_data_attributes': v8_attributes.filter_lazy_data_attributes(attributes),
+        'origin_trial_attributes': v8_attributes.filter_origin_trial_enabled(attributes),
+        'runtime_enabled_attributes': v8_attributes.filter_runtime_enabled(attributes),
     })
 
     # Methods
diff --git a/third_party/WebKit/Source/bindings/templates/interface.h.tmpl b/third_party/WebKit/Source/bindings/templates/interface.h.tmpl
index 3f22aa7..e852554 100644
--- a/third_party/WebKit/Source/bindings/templates/interface.h.tmpl
+++ b/third_party/WebKit/Source/bindings/templates/interface.h.tmpl
@@ -13,7 +13,7 @@
 {% if has_event_constructor %}
 class Dictionary;
 {% endif %}
-{% if attributes|origin_trial_enabled_attributes %}
+{% if origin_trial_attributes %}
 class ScriptState;
 {% endif %}
 {% if named_constructor %}
diff --git a/third_party/WebKit/Source/bindings/templates/interface_base.cpp.tmpl b/third_party/WebKit/Source/bindings/templates/interface_base.cpp.tmpl
index e61d2b0d..ce55c9f 100644
--- a/third_party/WebKit/Source/bindings/templates/interface_base.cpp.tmpl
+++ b/third_party/WebKit/Source/bindings/templates/interface_base.cpp.tmpl
@@ -312,7 +312,7 @@
 {##############################################################################}
 {% block install_attributes %}
 {% from 'attributes.cpp.tmpl' import attribute_configuration with context %}
-{% if attributes | has_attribute_configuration %}
+{% if data_attributes %}
 // Suppress warning: global constructors, because AttributeConfiguration is trivial
 // and does not depend on another global objects.
 #if defined(COMPONENT_BUILD) && defined(WIN32) && COMPILER(CLANG)
@@ -320,8 +320,8 @@
 #pragma clang diagnostic ignored "-Wglobal-constructors"
 #endif
 const V8DOMConfiguration::AttributeConfiguration {{v8_class}}Attributes[] = {
-    {% for attribute in attributes | has_attribute_configuration %}
-    {{attribute_configuration(attribute)}},
+    {% for data_attribute in data_attributes %}
+    {{attribute_configuration(data_attribute)}},
     {% endfor %}
 };
 #if defined(COMPONENT_BUILD) && defined(WIN32) && COMPILER(CLANG)
@@ -333,7 +333,7 @@
 {##############################################################################}
 {% block install_lazy_data_attributes %}
 {% from 'attributes.cpp.tmpl' import attribute_configuration with context %}
-{% if attributes | has_lazy_data_attribute_configuration %}
+{% if lazy_data_attributes %}
 // Suppress warning: global constructors, because AttributeConfiguration is trivial
 // and does not depend on another global objects.
 #if defined(COMPONENT_BUILD) && defined(WIN32) && COMPILER(CLANG)
@@ -341,8 +341,8 @@
 #pragma clang diagnostic ignored "-Wglobal-constructors"
 #endif
 const V8DOMConfiguration::AttributeConfiguration {{v8_class}}LazyDataAttributes[] = {
-    {% for attribute in attributes | has_lazy_data_attribute_configuration %}
-    {{attribute_configuration(attribute)}},
+    {% for data_attribute in lazy_data_attributes %}
+    {{attribute_configuration(data_attribute)}},
     {% endfor %}
 };
 #if defined(COMPONENT_BUILD) && defined(WIN32) && COMPILER(CLANG)
@@ -354,10 +354,10 @@
 {##############################################################################}
 {% block install_accessors %}
 {% from 'attributes.cpp.tmpl' import attribute_configuration with context %}
-{% if attributes | has_accessor_configuration %}
+{% if accessors %}
 const V8DOMConfiguration::AccessorConfiguration {{v8_class}}Accessors[] = {
-    {% for attribute in attributes | has_accessor_configuration %}
-    {{attribute_configuration(attribute)}},
+    {% for accessor in accessors %}
+    {{attribute_configuration(accessor)}},
     {% endfor %}
 };
 
@@ -433,13 +433,13 @@
   {% if constants %}
   {{install_constants() | indent(2)}}
   {% endif %}
-  {% if attributes | has_attribute_configuration %}
+  {% if data_attributes %}
   V8DOMConfiguration::installAttributes(isolate, world, instanceTemplate, prototypeTemplate, {{'%sAttributes' % v8_class}}, {{'WTF_ARRAY_LENGTH(%sAttributes)' % v8_class}});
   {% endif %}
-  {% if attributes | has_lazy_data_attribute_configuration %}
+  {% if lazy_data_attributes %}
   V8DOMConfiguration::installLazyDataAttributes(isolate, world, instanceTemplate, prototypeTemplate, {{'%sLazyDataAttributes' % v8_class}}, {{'WTF_ARRAY_LENGTH(%sLazyDataAttributes)' % v8_class}});
   {% endif %}
-  {% if attributes | has_accessor_configuration %}
+  {% if accessors %}
   V8DOMConfiguration::installAccessors(isolate, world, instanceTemplate, prototypeTemplate, interfaceTemplate, signature, {{'%sAccessors' % v8_class}}, {{'WTF_ARRAY_LENGTH(%sAccessors)' % v8_class}});
   {% endif %}
   {% if methods | has_method_configuration(is_partial) %}
@@ -456,7 +456,7 @@
   instanceTemplate->SetAccessCheckCallbackAndHandler({{cpp_class}}V8Internal::securityCheck, v8::NamedPropertyHandlerConfiguration({{cross_origin_named_getter}}, {{cross_origin_named_setter}}, nullptr, nullptr, {{cross_origin_named_enumerator}}), v8::IndexedPropertyHandlerConfiguration({{cross_origin_indexed_getter}}), v8::External::New(isolate, const_cast<WrapperTypeInfo*>(&{{v8_class}}::wrapperTypeInfo)));
   {% endif %}
 
-  {% for group in attributes | purely_runtime_enabled_attributes | groupby('runtime_feature_name') %}
+  {% for group in runtime_enabled_attributes | groupby('runtime_feature_name') %}
   if ({{group.list[0].runtime_enabled_function}}()) {
     {% for attribute in group.list | unique_by('name') | sort %}
     {% if attribute.is_data_type_property %}
diff --git a/third_party/WebKit/Source/bindings/templates/partial_interface.h.tmpl b/third_party/WebKit/Source/bindings/templates/partial_interface.h.tmpl
index 29ad9c1..6fb89656 100644
--- a/third_party/WebKit/Source/bindings/templates/partial_interface.h.tmpl
+++ b/third_party/WebKit/Source/bindings/templates/partial_interface.h.tmpl
@@ -10,7 +10,7 @@
 
 namespace blink {
 
-{% if attributes|origin_trial_enabled_attributes %}
+{% if origin_trial_attributes %}
 class ScriptState;
 {% endif %}
 
diff --git a/third_party/WebKit/Source/core/BUILD.gn b/third_party/WebKit/Source/core/BUILD.gn
index 7dda8a1..58fb912 100644
--- a/third_party/WebKit/Source/core/BUILD.gn
+++ b/third_party/WebKit/Source/core/BUILD.gn
@@ -1148,8 +1148,10 @@
     "fetch/MemoryCacheCorrectnessTestHelper.h",
     "fetch/MemoryCacheTest.cpp",
     "fetch/MockFetchContext.h",
-    "fetch/MockResourceClients.cpp",
-    "fetch/MockResourceClients.h",
+    "fetch/MockImageResourceClient.cpp",
+    "fetch/MockImageResourceClient.h",
+    "fetch/MockResourceClient.cpp",
+    "fetch/MockResourceClient.h",
     "fetch/MultipartImageResourceParserTest.cpp",
     "fetch/RawResourceTest.cpp",
     "fetch/ResourceFetcherTest.cpp",
diff --git a/third_party/WebKit/Source/core/animation/Animation.cpp b/third_party/WebKit/Source/core/animation/Animation.cpp
index 6638823..9b95ae8 100644
--- a/third_party/WebKit/Source/core/animation/Animation.cpp
+++ b/third_party/WebKit/Source/core/animation/Animation.cpp
@@ -99,7 +99,6 @@
       m_compositorState(nullptr),
       m_compositorPending(false),
       m_compositorGroup(0),
-      m_preFinalizerRegistered(false),
       m_currentTimePending(false),
       m_stateIsBeingUpdated(false),
       m_effectSuppressed(false) {
@@ -115,7 +114,8 @@
 }
 
 Animation::~Animation() {
-  destroyCompositorPlayer();
+  // Verify that m_compositorPlayer has been disposed of.
+  DCHECK(!m_compositorPlayer);
 }
 
 void Animation::dispose() {
@@ -910,17 +910,9 @@
 void Animation::createCompositorPlayer() {
   if (Platform::current()->isThreadedAnimationEnabled() &&
       !m_compositorPlayer) {
-    // We only need to pre-finalize if we are running animations on the
-    // compositor.
-    if (!m_preFinalizerRegistered) {
-      ThreadState::current()->registerPreFinalizer(this);
-      m_preFinalizerRegistered = true;
-    }
-
     DCHECK(Platform::current()->compositorSupport());
-    m_compositorPlayer = CompositorAnimationPlayer::create();
+    m_compositorPlayer = CompositorAnimationPlayerHolder::create(this);
     DCHECK(m_compositorPlayer);
-    m_compositorPlayer->setAnimationDelegate(this);
     attachCompositorTimeline();
   }
 
@@ -932,8 +924,8 @@
 
   if (m_compositorPlayer) {
     detachCompositorTimeline();
-    m_compositorPlayer->setAnimationDelegate(nullptr);
-    m_compositorPlayer.reset();
+    m_compositorPlayer->detach();
+    m_compositorPlayer = nullptr;
   }
 }
 
@@ -966,8 +958,8 @@
 }
 
 void Animation::detachCompositedLayers() {
-  if (m_compositorPlayer && m_compositorPlayer->isElementAttached())
-    m_compositorPlayer->detachElement();
+  if (m_compositorPlayer && m_compositorPlayer->player()->isElementAttached())
+    m_compositorPlayer->player()->detachElement();
 }
 
 void Animation::notifyAnimationStarted(double monotonicTime, int group) {
@@ -1126,8 +1118,36 @@
   visitor->trace(m_pendingCancelledEvent);
   visitor->trace(m_finishedPromise);
   visitor->trace(m_readyPromise);
+  visitor->trace(m_compositorPlayer);
   EventTargetWithInlineData::trace(visitor);
   SuspendableObject::trace(visitor);
 }
 
+Animation::CompositorAnimationPlayerHolder*
+Animation::CompositorAnimationPlayerHolder::create(Animation* animation) {
+  return new CompositorAnimationPlayerHolder(animation);
+}
+
+Animation::CompositorAnimationPlayerHolder::CompositorAnimationPlayerHolder(
+    Animation* animation)
+    : m_animation(animation) {
+  ThreadState::current()->registerPreFinalizer(this);
+  m_compositorPlayer = CompositorAnimationPlayer::create();
+  m_compositorPlayer->setAnimationDelegate(m_animation);
+}
+
+void Animation::CompositorAnimationPlayerHolder::dispose() {
+  if (!m_animation)
+    return;
+  m_animation->dispose();
+  DCHECK(!m_animation);
+  DCHECK(!m_compositorPlayer);
+}
+
+void Animation::CompositorAnimationPlayerHolder::detach() {
+  DCHECK(m_compositorPlayer);
+  m_compositorPlayer->setAnimationDelegate(nullptr);
+  m_animation = nullptr;
+  m_compositorPlayer.reset();
+}
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/animation/Animation.h b/third_party/WebKit/Source/core/animation/Animation.h
index ccaf0de..6d9f357 100644
--- a/third_party/WebKit/Source/core/animation/Animation.h
+++ b/third_party/WebKit/Source/core/animation/Animation.h
@@ -62,7 +62,6 @@
                                     public CompositorAnimationPlayerClient {
   DEFINE_WRAPPERTYPEINFO();
   USING_GARBAGE_COLLECTED_MIXIN(Animation);
-  USING_PRE_FINALIZER(Animation, dispose);
 
  public:
   enum AnimationPlayState { Unset, Idle, Pending, Running, Paused, Finished };
@@ -162,7 +161,7 @@
   void notifyStartTime(double timelineTime);
   // CompositorAnimationPlayerClient implementation.
   CompositorAnimationPlayer* compositorPlayer() const override {
-    return m_compositorPlayer.get();
+    return m_compositorPlayer ? m_compositorPlayer->player() : nullptr;
   }
 
   bool affects(const Element&, CSSPropertyID) const;
@@ -300,6 +299,33 @@
     CompositorPendingChange m_compositorPendingChange;
   };
 
+  // CompositorAnimationPlayer objects need to eagerly sever
+  // their connection to their Animation delegate; use a separate
+  // 'holder' on-heap object to accomplish that.
+  class CompositorAnimationPlayerHolder
+      : public GarbageCollectedFinalized<CompositorAnimationPlayerHolder> {
+    USING_PRE_FINALIZER(CompositorAnimationPlayerHolder, dispose);
+
+   public:
+    static CompositorAnimationPlayerHolder* create(Animation*);
+
+    void detach();
+
+    DEFINE_INLINE_TRACE() { visitor->trace(m_animation); }
+
+    CompositorAnimationPlayer* player() const {
+      return m_compositorPlayer.get();
+    }
+
+   private:
+    explicit CompositorAnimationPlayerHolder(Animation*);
+
+    void dispose();
+
+    std::unique_ptr<CompositorAnimationPlayer> m_compositorPlayer;
+    Member<Animation> m_animation;
+  };
+
   // This mirrors the known compositor state. It is created when a compositor
   // animation is started. Updated once the start time is known and each time
   // modifications are pushed to the compositor.
@@ -307,8 +333,7 @@
   bool m_compositorPending;
   int m_compositorGroup;
 
-  std::unique_ptr<CompositorAnimationPlayer> m_compositorPlayer;
-  bool m_preFinalizerRegistered;
+  Member<CompositorAnimationPlayerHolder> m_compositorPlayer;
 
   bool m_currentTimePending;
   bool m_stateIsBeingUpdated;
diff --git a/third_party/WebKit/Source/core/dom/DOMMatrix.cpp b/third_party/WebKit/Source/core/dom/DOMMatrix.cpp
index 5ec28a8..59c6ae4 100644
--- a/third_party/WebKit/Source/core/dom/DOMMatrix.cpp
+++ b/third_party/WebKit/Source/core/dom/DOMMatrix.cpp
@@ -4,14 +4,6 @@
 
 #include "core/dom/DOMMatrix.h"
 
-#include "core/css/CSSIdentifierValue.h"
-#include "core/css/CSSToLengthConversionData.h"
-#include "core/css/CSSValueList.h"
-#include "core/css/parser/CSSParser.h"
-#include "core/css/resolver/TransformBuilder.h"
-#include "core/layout/api/LayoutViewItem.h"
-#include "core/style/ComputedStyle.h"
-
 namespace blink {
 
 DOMMatrix* DOMMatrix::create(ExceptionState& exceptionState) {
@@ -29,6 +21,13 @@
   return new DOMMatrix(transformationMatrix, transformationMatrix.isAffine());
 }
 
+DOMMatrix* DOMMatrix::create(const String& transformList,
+                             ExceptionState& exceptionState) {
+  DOMMatrix* matrix = new DOMMatrix(TransformationMatrix());
+  matrix->setMatrixValueFromString(transformList, exceptionState);
+  return matrix;
+}
+
 DOMMatrix* DOMMatrix::create(Vector<double> sequence,
                              ExceptionState& exceptionState) {
   if (sequence.size() != 6 && sequence.size() != 16) {
@@ -261,50 +260,7 @@
 
 DOMMatrix* DOMMatrix::setMatrixValue(const String& inputString,
                                      ExceptionState& exceptionState) {
-  DEFINE_STATIC_LOCAL(String, identityMatrix2D, ("matrix(1, 0, 0, 1, 0, 0)"));
-  String string = inputString;
-  if (string.isEmpty())
-    string = identityMatrix2D;
-
-  const CSSValue* value =
-      CSSParser::parseSingleValue(CSSPropertyTransform, string);
-
-  if (!value || value->isCSSWideKeyword()) {
-    exceptionState.throwDOMException(SyntaxError,
-                                     "Failed to parse '" + inputString + "'.");
-    return nullptr;
-  }
-
-  if (value->isIdentifierValue()) {
-    DCHECK(toCSSIdentifierValue(value)->getValueID() == CSSValueNone);
-    m_matrix->makeIdentity();
-    m_is2D = true;
-    return this;
-  }
-
-  if (TransformBuilder::hasRelativeLengths(toCSSValueList(*value))) {
-    exceptionState.throwDOMException(SyntaxError,
-                                     "Relative lengths not supported.");
-    return nullptr;
-  }
-
-  const ComputedStyle& initialStyle = ComputedStyle::initialStyle();
-  TransformOperations operations = TransformBuilder::createTransformOperations(
-      *value, CSSToLengthConversionData(&initialStyle, &initialStyle,
-                                        LayoutViewItem(nullptr), 1.0f));
-
-  if (operations.dependsOnBoxSize()) {
-    exceptionState.throwDOMException(SyntaxError,
-                                     "The transformation depends on the box "
-                                     "size, which is not supported.");
-    return nullptr;
-  }
-
-  m_matrix->makeIdentity();
-  operations.apply(FloatSize(0, 0), *m_matrix);
-
-  m_is2D = !operations.has3DOperation();
-
+  setMatrixValueFromString(inputString, exceptionState);
   return this;
 }
 
diff --git a/third_party/WebKit/Source/core/dom/DOMMatrix.h b/third_party/WebKit/Source/core/dom/DOMMatrix.h
index d9913c1..752f2fb 100644
--- a/third_party/WebKit/Source/core/dom/DOMMatrix.h
+++ b/third_party/WebKit/Source/core/dom/DOMMatrix.h
@@ -19,6 +19,7 @@
   static DOMMatrix* create(DOMMatrixReadOnly*,
                            ExceptionState& = ASSERT_NO_EXCEPTION);
   static DOMMatrix* create(const SkMatrix44&, ExceptionState&);
+  static DOMMatrix* create(const String&, ExceptionState&);
   static DOMMatrix* create(Vector<double>, ExceptionState&);
   static DOMMatrix* fromFloat32Array(DOMFloat32Array*, ExceptionState&);
   static DOMMatrix* fromFloat64Array(DOMFloat64Array*, ExceptionState&);
diff --git a/third_party/WebKit/Source/core/dom/DOMMatrix.idl b/third_party/WebKit/Source/core/dom/DOMMatrix.idl
index 9e893b6..93621ed 100644
--- a/third_party/WebKit/Source/core/dom/DOMMatrix.idl
+++ b/third_party/WebKit/Source/core/dom/DOMMatrix.idl
@@ -6,6 +6,7 @@
 
 [
     Constructor,
+    Constructor(DOMString transformList),
     Constructor(sequence<unrestricted double> numberSequence),
     RaisesException=Constructor,
     // FIXME: Should implement more constructors (See: crbug.com/388780)
diff --git a/third_party/WebKit/Source/core/dom/DOMMatrixReadOnly.cpp b/third_party/WebKit/Source/core/dom/DOMMatrixReadOnly.cpp
index a3cc1da..e4c1ed95 100644
--- a/third_party/WebKit/Source/core/dom/DOMMatrixReadOnly.cpp
+++ b/third_party/WebKit/Source/core/dom/DOMMatrixReadOnly.cpp
@@ -5,10 +5,17 @@
 #include "core/dom/DOMMatrixReadOnly.h"
 
 #include "bindings/core/v8/V8ObjectBuilder.h"
+#include "core/css/CSSIdentifierValue.h"
+#include "core/css/CSSToLengthConversionData.h"
+#include "core/css/CSSValueList.h"
+#include "core/css/parser/CSSParser.h"
+#include "core/css/resolver/TransformBuilder.h"
 #include "core/dom/DOMMatrix.h"
 #include "core/dom/DOMMatrixInit.h"
 #include "core/dom/DOMPoint.h"
 #include "core/dom/DOMPointInit.h"
+#include "core/layout/api/LayoutViewItem.h"
+#include "core/style/ComputedStyle.h"
 
 namespace blink {
 namespace {
@@ -89,6 +96,13 @@
   return new DOMMatrixReadOnly(TransformationMatrix());
 }
 
+DOMMatrixReadOnly* DOMMatrixReadOnly::create(const String& transformList,
+                                             ExceptionState& exceptionState) {
+  DOMMatrixReadOnly* matrix = new DOMMatrixReadOnly(TransformationMatrix());
+  matrix->setMatrixValueFromString(transformList, exceptionState);
+  return matrix;
+}
+
 DOMMatrixReadOnly* DOMMatrixReadOnly::create(Vector<double> sequence,
                                              ExceptionState& exceptionState) {
   if (sequence.size() != 6 && sequence.size() != 16) {
@@ -332,4 +346,53 @@
   return result.scriptValue();
 }
 
+void DOMMatrixReadOnly::setMatrixValueFromString(
+    const String& inputString,
+    ExceptionState& exceptionState) {
+  DEFINE_STATIC_LOCAL(String, identityMatrix2D, ("matrix(1, 0, 0, 1, 0, 0)"));
+  String string = inputString;
+  if (string.isEmpty())
+    string = identityMatrix2D;
+
+  const CSSValue* value =
+      CSSParser::parseSingleValue(CSSPropertyTransform, string);
+
+  if (!value || value->isCSSWideKeyword()) {
+    exceptionState.throwDOMException(SyntaxError,
+                                     "Failed to parse '" + inputString + "'.");
+    return;
+  }
+
+  if (value->isIdentifierValue()) {
+    DCHECK(toCSSIdentifierValue(value)->getValueID() == CSSValueNone);
+    m_matrix->makeIdentity();
+    m_is2D = true;
+    return;
+  }
+
+  if (TransformBuilder::hasRelativeLengths(toCSSValueList(*value))) {
+    exceptionState.throwDOMException(SyntaxError,
+                                     "Lengths must be absolute, not relative");
+    return;
+  }
+
+  const ComputedStyle& initialStyle = ComputedStyle::initialStyle();
+  TransformOperations operations = TransformBuilder::createTransformOperations(
+      *value, CSSToLengthConversionData(&initialStyle, &initialStyle,
+                                        LayoutViewItem(nullptr), 1.0f));
+
+  if (operations.dependsOnBoxSize()) {
+    exceptionState.throwDOMException(
+        SyntaxError, "Lengths must be absolute, not depend on the box size");
+    return;
+  }
+
+  m_matrix->makeIdentity();
+  operations.apply(FloatSize(0, 0), *m_matrix);
+
+  m_is2D = !operations.has3DOperation();
+
+  return;
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/dom/DOMMatrixReadOnly.h b/third_party/WebKit/Source/core/dom/DOMMatrixReadOnly.h
index 639ade8b..c78bfe5 100644
--- a/third_party/WebKit/Source/core/dom/DOMMatrixReadOnly.h
+++ b/third_party/WebKit/Source/core/dom/DOMMatrixReadOnly.h
@@ -26,6 +26,7 @@
 
  public:
   static DOMMatrixReadOnly* create(ExceptionState&);
+  static DOMMatrixReadOnly* create(const String&, ExceptionState&);
   static DOMMatrixReadOnly* create(Vector<double>, ExceptionState&);
   static DOMMatrixReadOnly* fromFloat32Array(DOMFloat32Array*, ExceptionState&);
   static DOMMatrixReadOnly* fromFloat64Array(DOMFloat64Array*, ExceptionState&);
@@ -101,6 +102,7 @@
 
  protected:
   DOMMatrixReadOnly() {}
+  DOMMatrixReadOnly(const String&, ExceptionState&);
   DOMMatrixReadOnly(const TransformationMatrix&, bool is2D = true);
 
   template <typename T>
@@ -122,6 +124,8 @@
     }
   }
 
+  void setMatrixValueFromString(const String&, ExceptionState&);
+
   static bool validateAndFixup(DOMMatrixInit&, ExceptionState&);
   // TransformationMatrix needs to be 16-byte aligned. PartitionAlloc
   // supports 16-byte alignment but Oilpan doesn't. So we use an std::unique_ptr
diff --git a/third_party/WebKit/Source/core/dom/DOMMatrixReadOnly.idl b/third_party/WebKit/Source/core/dom/DOMMatrixReadOnly.idl
index e1d34736..a67878b 100644
--- a/third_party/WebKit/Source/core/dom/DOMMatrixReadOnly.idl
+++ b/third_party/WebKit/Source/core/dom/DOMMatrixReadOnly.idl
@@ -6,6 +6,7 @@
 
 [
     Constructor,
+    Constructor(DOMString transformList),
     Constructor(sequence<unrestricted double> numberSequence),
     RaisesException=Constructor,
     // FIXME: Exposed=(Window,Worker)
diff --git a/third_party/WebKit/Source/core/dom/NonDocumentTypeChildNode.idl b/third_party/WebKit/Source/core/dom/NonDocumentTypeChildNode.idl
index b2883c4..ff4cacc 100644
--- a/third_party/WebKit/Source/core/dom/NonDocumentTypeChildNode.idl
+++ b/third_party/WebKit/Source/core/dom/NonDocumentTypeChildNode.idl
@@ -8,6 +8,6 @@
     LegacyTreatAsPartialInterface,
     NoInterfaceObject, // Always used on target of 'implements'
 ] interface NonDocumentTypeChildNode {
-    [PerWorldBindings] readonly attribute Element previousElementSibling;
-    [PerWorldBindings] readonly attribute Element nextElementSibling;
+    [PerWorldBindings] readonly attribute Element? previousElementSibling;
+    [PerWorldBindings] readonly attribute Element? nextElementSibling;
 };
diff --git a/third_party/WebKit/Source/core/fetch/ClientHintsPreferences.cpp b/third_party/WebKit/Source/core/fetch/ClientHintsPreferences.cpp
index 4b5e7d92..5b0c4f4 100644
--- a/third_party/WebKit/Source/core/fetch/ClientHintsPreferences.cpp
+++ b/third_party/WebKit/Source/core/fetch/ClientHintsPreferences.cpp
@@ -4,7 +4,6 @@
 
 #include "core/fetch/ClientHintsPreferences.h"
 
-#include "core/fetch/ResourceFetcher.h"
 #include "platform/RuntimeEnabledFeatures.h"
 #include "platform/network/HTTPParsers.h"
 
@@ -24,27 +23,27 @@
 
 void ClientHintsPreferences::updateFromAcceptClientHintsHeader(
     const String& headerValue,
-    ResourceFetcher* fetcher) {
+    Context* context) {
   if (!RuntimeEnabledFeatures::clientHintsEnabled() || headerValue.isEmpty())
     return;
 
   CommaDelimitedHeaderSet acceptClientHintsHeader;
   parseCommaDelimitedHeader(headerValue, acceptClientHintsHeader);
   if (acceptClientHintsHeader.contains("dpr")) {
-    if (fetcher)
-      fetcher->context().countClientHintsDPR();
+    if (context)
+      context->countClientHintsDPR();
     m_shouldSendDPR = true;
   }
 
   if (acceptClientHintsHeader.contains("width")) {
-    if (fetcher)
-      fetcher->context().countClientHintsResourceWidth();
+    if (context)
+      context->countClientHintsResourceWidth();
     m_shouldSendResourceWidth = true;
   }
 
   if (acceptClientHintsHeader.contains("viewport-width")) {
-    if (fetcher)
-      fetcher->context().countClientHintsViewportWidth();
+    if (context)
+      context->countClientHintsViewportWidth();
     m_shouldSendViewportWidth = true;
   }
 }
diff --git a/third_party/WebKit/Source/core/fetch/ClientHintsPreferences.h b/third_party/WebKit/Source/core/fetch/ClientHintsPreferences.h
index 7fdddc5..996fd3aa 100644
--- a/third_party/WebKit/Source/core/fetch/ClientHintsPreferences.h
+++ b/third_party/WebKit/Source/core/fetch/ClientHintsPreferences.h
@@ -11,17 +11,24 @@
 
 namespace blink {
 
-class ResourceFetcher;
-
 class CORE_EXPORT ClientHintsPreferences {
   DISALLOW_NEW();
 
  public:
+  class Context {
+   public:
+    virtual void countClientHintsDPR() = 0;
+    virtual void countClientHintsResourceWidth() = 0;
+    virtual void countClientHintsViewportWidth() = 0;
+
+   protected:
+    virtual ~Context() {}
+  };
+
   ClientHintsPreferences();
 
   void updateFrom(const ClientHintsPreferences&);
-  void updateFromAcceptClientHintsHeader(const String& headerValue,
-                                         ResourceFetcher*);
+  void updateFromAcceptClientHintsHeader(const String& headerValue, Context*);
 
   bool shouldSendDPR() const { return m_shouldSendDPR; }
   void setShouldSendDPR(bool should) { m_shouldSendDPR = should; }
diff --git a/third_party/WebKit/Source/core/fetch/FetchContext.h b/third_party/WebKit/Source/core/fetch/FetchContext.h
index 5c31515..818fef96 100644
--- a/third_party/WebKit/Source/core/fetch/FetchContext.h
+++ b/third_party/WebKit/Source/core/fetch/FetchContext.h
@@ -53,6 +53,13 @@
 
 enum FetchResourceType { FetchMainResource, FetchSubresource };
 
+// The FetchContext is an interface for performing context specific processing
+// in response to events in the ResourceFetcher. The ResourceFetcher or its job
+// class, ResourceLoader, may call the methods on a FetchContext.
+//
+// Any processing that depends on core/ components outside core/fetch/ should
+// be implemented on a subclass of this interface, and then exposed to the
+// ResourceFetcher via this interface.
 class CORE_EXPORT FetchContext
     : public GarbageCollectedFinalized<FetchContext> {
   WTF_MAKE_NONCOPYABLE(FetchContext);
@@ -66,9 +73,6 @@
   DEFINE_INLINE_VIRTUAL_TRACE() {}
 
   virtual bool isLiveContext() { return false; }
-  virtual void countClientHintsDPR() {}
-  virtual void countClientHintsResourceWidth() {}
-  virtual void countClientHintsViewportWidth() {}
 
   virtual void addAdditionalRequestHeaders(ResourceRequest&, FetchResourceType);
   virtual CachePolicy getCachePolicy() const;
diff --git a/third_party/WebKit/Source/core/fetch/ImageResourceTest.cpp b/third_party/WebKit/Source/core/fetch/ImageResourceTest.cpp
index 7a89810..45595b4 100644
--- a/third_party/WebKit/Source/core/fetch/ImageResourceTest.cpp
+++ b/third_party/WebKit/Source/core/fetch/ImageResourceTest.cpp
@@ -33,7 +33,8 @@
 #include "core/fetch/FetchInitiatorInfo.h"
 #include "core/fetch/FetchRequest.h"
 #include "core/fetch/MemoryCache.h"
-#include "core/fetch/MockResourceClients.h"
+#include "core/fetch/MockImageResourceClient.h"
+#include "core/fetch/MockResourceClient.h"
 #include "core/fetch/ResourceFetcher.h"
 #include "core/fetch/ResourceLoader.h"
 #include "core/fetch/UniqueIdentifier.h"
diff --git a/third_party/WebKit/Source/core/fetch/MemoryCacheTest.cpp b/third_party/WebKit/Source/core/fetch/MemoryCacheTest.cpp
index 4e9603fe..a6465be 100644
--- a/third_party/WebKit/Source/core/fetch/MemoryCacheTest.cpp
+++ b/third_party/WebKit/Source/core/fetch/MemoryCacheTest.cpp
@@ -30,7 +30,7 @@
 
 #include "core/fetch/MemoryCache.h"
 
-#include "core/fetch/MockResourceClients.h"
+#include "core/fetch/MockResourceClient.h"
 #include "core/fetch/RawResource.h"
 #include "platform/network/ResourceRequest.h"
 #include "platform/testing/UnitTestHelpers.h"
diff --git a/third_party/WebKit/Source/core/fetch/MockResourceClients.cpp b/third_party/WebKit/Source/core/fetch/MockImageResourceClient.cpp
similarity index 62%
rename from third_party/WebKit/Source/core/fetch/MockResourceClients.cpp
rename to third_party/WebKit/Source/core/fetch/MockImageResourceClient.cpp
index 8c8c861..9705278 100644
--- a/third_party/WebKit/Source/core/fetch/MockResourceClients.cpp
+++ b/third_party/WebKit/Source/core/fetch/MockImageResourceClient.cpp
@@ -1,8 +1,8 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
+// Copyright 2016 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "core/fetch/MockResourceClients.h"
+#include "core/fetch/MockImageResourceClient.h"
 
 #include "core/fetch/ImageResource.h"
 #include "core/fetch/ImageResourceContent.h"
@@ -10,39 +10,6 @@
 
 namespace blink {
 
-MockResourceClient::MockResourceClient(Resource* resource)
-    : m_resource(resource),
-      m_notifyFinishedCalled(false),
-      m_encodedSizeOnNotifyFinished(0) {
-  ThreadState::current()->registerPreFinalizer(this);
-  m_resource->addClient(this);
-}
-
-MockResourceClient::~MockResourceClient() {}
-
-void MockResourceClient::notifyFinished(Resource* resource) {
-  ASSERT_FALSE(m_notifyFinishedCalled);
-  m_notifyFinishedCalled = true;
-  m_encodedSizeOnNotifyFinished = resource->encodedSize();
-}
-
-void MockResourceClient::removeAsClient() {
-  m_resource->removeClient(this);
-  m_resource = nullptr;
-}
-
-void MockResourceClient::dispose() {
-  if (m_resource) {
-    m_resource->removeClient(this);
-    m_resource = nullptr;
-  }
-}
-
-DEFINE_TRACE(MockResourceClient) {
-  visitor->trace(m_resource);
-  ResourceClient::trace(visitor);
-}
-
 MockImageResourceClient::MockImageResourceClient(ImageResource* resource)
     : MockResourceClient(resource),
       m_imageChangedCount(0),
diff --git a/third_party/WebKit/Source/core/fetch/MockImageResourceClient.h b/third_party/WebKit/Source/core/fetch/MockImageResourceClient.h
new file mode 100644
index 0000000..ecbfb8a
--- /dev/null
+++ b/third_party/WebKit/Source/core/fetch/MockImageResourceClient.h
@@ -0,0 +1,50 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MockImageResourceClient_h
+#define MockImageResourceClient_h
+
+#include "core/fetch/ImageResource.h"
+#include "core/fetch/ImageResourceContent.h"
+#include "core/fetch/ImageResourceObserver.h"
+#include "core/fetch/MockResourceClient.h"
+
+namespace blink {
+
+class MockImageResourceClient final : public MockResourceClient,
+                                      public ImageResourceObserver {
+ public:
+  explicit MockImageResourceClient(ImageResource*);
+  ~MockImageResourceClient() override;
+
+  void imageNotifyFinished(ImageResourceContent*) override;
+  void imageChanged(ImageResourceContent*, const IntRect*) override;
+
+  String debugName() const override { return "MockImageResourceClient"; }
+
+  bool notifyFinishedCalled() const override;
+
+  void removeAsClient() override;
+  void dispose() override;
+
+  int imageChangedCount() const { return m_imageChangedCount; }
+  int imageNotifyFinishedCount() const { return m_imageNotifyFinishedCount; }
+
+  size_t encodedSizeOnLastImageChanged() const {
+    return m_encodedSizeOnLastImageChanged;
+  }
+  size_t encodedSizeOnImageNotifyFinished() const {
+    return m_encodedSizeOnImageNotifyFinished;
+  }
+
+ private:
+  int m_imageChangedCount;
+  size_t m_encodedSizeOnLastImageChanged;
+  int m_imageNotifyFinishedCount;
+  size_t m_encodedSizeOnImageNotifyFinished;
+};
+
+}  // namespace blink
+
+#endif  // MockImageResourceClient_h
diff --git a/third_party/WebKit/Source/core/fetch/MockResourceClient.cpp b/third_party/WebKit/Source/core/fetch/MockResourceClient.cpp
new file mode 100644
index 0000000..0d956bc4
--- /dev/null
+++ b/third_party/WebKit/Source/core/fetch/MockResourceClient.cpp
@@ -0,0 +1,44 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "core/fetch/MockResourceClient.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace blink {
+
+MockResourceClient::MockResourceClient(Resource* resource)
+    : m_resource(resource),
+      m_notifyFinishedCalled(false),
+      m_encodedSizeOnNotifyFinished(0) {
+  ThreadState::current()->registerPreFinalizer(this);
+  m_resource->addClient(this);
+}
+
+MockResourceClient::~MockResourceClient() {}
+
+void MockResourceClient::notifyFinished(Resource* resource) {
+  ASSERT_FALSE(m_notifyFinishedCalled);
+  m_notifyFinishedCalled = true;
+  m_encodedSizeOnNotifyFinished = resource->encodedSize();
+}
+
+void MockResourceClient::removeAsClient() {
+  m_resource->removeClient(this);
+  m_resource = nullptr;
+}
+
+void MockResourceClient::dispose() {
+  if (m_resource) {
+    m_resource->removeClient(this);
+    m_resource = nullptr;
+  }
+}
+
+DEFINE_TRACE(MockResourceClient) {
+  visitor->trace(m_resource);
+  ResourceClient::trace(visitor);
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/core/fetch/MockResourceClients.h b/third_party/WebKit/Source/core/fetch/MockResourceClient.h
similarity index 66%
rename from third_party/WebKit/Source/core/fetch/MockResourceClients.h
rename to third_party/WebKit/Source/core/fetch/MockResourceClient.h
index 90fe127..f6d9c0a9 100644
--- a/third_party/WebKit/Source/core/fetch/MockResourceClients.h
+++ b/third_party/WebKit/Source/core/fetch/MockResourceClient.h
@@ -28,12 +28,9 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef MockResourceClients_h
-#define MockResourceClients_h
+#ifndef MockResourceClient_h
+#define MockResourceClient_h
 
-#include "core/fetch/ImageResource.h"
-#include "core/fetch/ImageResourceContent.h"
-#include "core/fetch/ImageResourceObserver.h"
 #include "core/fetch/Resource.h"
 #include "core/fetch/ResourceClient.h"
 #include "platform/heap/Handle.h"
@@ -68,39 +65,6 @@
   size_t m_encodedSizeOnNotifyFinished;
 };
 
-class MockImageResourceClient final : public MockResourceClient,
-                                      public ImageResourceObserver {
- public:
-  explicit MockImageResourceClient(ImageResource*);
-  ~MockImageResourceClient() override;
-
-  void imageNotifyFinished(ImageResourceContent*) override;
-  void imageChanged(ImageResourceContent*, const IntRect*) override;
-
-  String debugName() const override { return "MockImageResourceClient"; }
-
-  bool notifyFinishedCalled() const override;
-
-  void removeAsClient() override;
-  void dispose() override;
-
-  int imageChangedCount() const { return m_imageChangedCount; }
-  int imageNotifyFinishedCount() const { return m_imageNotifyFinishedCount; }
-
-  size_t encodedSizeOnLastImageChanged() const {
-    return m_encodedSizeOnLastImageChanged;
-  }
-  size_t encodedSizeOnImageNotifyFinished() const {
-    return m_encodedSizeOnImageNotifyFinished;
-  }
-
- private:
-  int m_imageChangedCount;
-  size_t m_encodedSizeOnLastImageChanged;
-  int m_imageNotifyFinishedCount;
-  size_t m_encodedSizeOnImageNotifyFinished;
-};
-
 }  // namespace blink
 
-#endif  // MockResourceClients_h
+#endif  // MockResourceClient_h
diff --git a/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp b/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp
index e54aa91..85003f3 100644
--- a/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp
+++ b/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp
@@ -28,7 +28,6 @@
 #include "core/fetch/ResourceFetcher.h"
 
 #include "bindings/core/v8/V8DOMActivityLogger.h"
-#include "core/fetch/CrossOriginAccessControl.h"
 #include "core/fetch/FetchContext.h"
 #include "core/fetch/FetchInitiatorTypeNames.h"
 #include "core/fetch/ImageResource.h"
@@ -97,12 +96,6 @@
     DEFINE_SINGLE_RESOURCE_HISTOGRAM(prefix, XSLStyleSheet)  \
   }
 
-bool IsCrossOrigin(const KURL& a, const KURL& b) {
-  RefPtr<SecurityOrigin> originA = SecurityOrigin::create(a);
-  RefPtr<SecurityOrigin> originB = SecurityOrigin::create(b);
-  return !originB->isSameSchemeHostPort(originA.get());
-}
-
 void addRedirectsToTimingInfo(Resource* resource, ResourceTimingInfo* info) {
   // Store redirect responses that were packed inside the final response.
   const auto& responses = resource->response().redirectResponses();
@@ -110,14 +103,13 @@
     const KURL& newURL = i + 1 < responses.size()
                              ? KURL(responses[i + 1].url())
                              : resource->resourceRequest().url();
-    bool crossOrigin = IsCrossOrigin(responses[i].url(), newURL);
+    bool crossOrigin =
+        !SecurityOrigin::areSameSchemeHostPort(responses[i].url(), newURL);
     info->addRedirect(responses[i], crossOrigin);
   }
 }
 
-}  // namespace
-
-static void RecordSriResourceIntegrityMismatchEvent(
+void RecordSriResourceIntegrityMismatchEvent(
     SriResourceIntegrityMismatchEvent event) {
   DEFINE_THREAD_SAFE_STATIC_LOCAL(
       EnumerationHistogram, integrityHistogram,
@@ -126,7 +118,7 @@
   integrityHistogram.count(event);
 }
 
-static ResourceLoadPriority typeToPriority(Resource::Type type) {
+ResourceLoadPriority typeToPriority(Resource::Type type) {
   switch (type) {
     case Resource::MainResource:
     case Resource::CSSStyleSheet:
@@ -158,6 +150,8 @@
   return ResourceLoadPriorityUnresolved;
 }
 
+}  // namespace
+
 ResourceLoadPriority ResourceFetcher::computeLoadPriority(
     Resource::Type type,
     const FetchRequest& request,
@@ -270,50 +264,6 @@
   return resource.get();
 }
 
-ResourceRequestBlockedReason ResourceFetcher::canAccessResponse(
-    Resource* resource,
-    const ResourceResponse& response) const {
-  // Redirects can change the response URL different from one of request.
-  bool forPreload = resource->isUnusedPreload();
-  ResourceRequestBlockedReason blockedReason =
-      context().canRequest(resource->getType(), resource->resourceRequest(),
-                           response.url(), resource->options(), forPreload,
-                           FetchRequest::UseDefaultOriginRestrictionForType);
-  if (blockedReason != ResourceRequestBlockedReason::None)
-    return blockedReason;
-
-  SecurityOrigin* sourceOrigin = resource->options().securityOrigin.get();
-  if (!sourceOrigin)
-    sourceOrigin = context().getSecurityOrigin();
-
-  if (sourceOrigin->canRequestNoSuborigin(response.url()))
-    return ResourceRequestBlockedReason::None;
-
-  // Use the original response instead of the 304 response for a successful
-  // revaldiation.
-  const ResourceResponse& responseForAccessControl =
-      (resource->isCacheValidator() && response.httpStatusCode() == 304)
-          ? resource->response()
-          : response;
-  String errorDescription;
-  if (!passesAccessControlCheck(
-          responseForAccessControl, resource->options().allowCredentials,
-          sourceOrigin, errorDescription,
-          resource->lastResourceRequest().requestContext())) {
-    resource->setCORSFailed();
-    if (!forPreload) {
-      String resourceType = Resource::resourceTypeToString(
-          resource->getType(), resource->options().initiatorInfo);
-      context().addConsoleMessage(
-          "Access to " + resourceType + " at '" + response.url().getString() +
-          "' from origin '" + sourceOrigin->toString() +
-          "' has been blocked by CORS policy: " + errorDescription);
-    }
-    return ResourceRequestBlockedReason::Other;
-  }
-  return ResourceRequestBlockedReason::None;
-}
-
 bool ResourceFetcher::isControlledByServiceWorker() const {
   return context().isControlledByServiceWorker();
 }
@@ -805,6 +755,21 @@
   }
 }
 
+void ResourceFetcher::recordResourceTimingOnRedirect(
+    Resource* resource,
+    const ResourceResponse& redirectResponse,
+    bool crossOrigin) {
+  ResourceTimingInfoMap::iterator it = m_resourceTimingInfoMap.find(resource);
+  if (it != m_resourceTimingInfoMap.end()) {
+    it->value->addRedirect(redirectResponse, crossOrigin);
+  }
+
+  if (resource->getType() == Resource::MainResource) {
+    DCHECK(m_navigationTimingInfo);
+    m_navigationTimingInfo->addRedirect(redirectResponse, crossOrigin);
+  }
+}
+
 ResourceFetcher::RevalidationPolicy
 ResourceFetcher::determineRevalidationPolicy(Resource::Type type,
                                              const FetchRequest& fetchRequest,
@@ -1148,23 +1113,32 @@
   return m_navigationTimingInfo.get();
 }
 
-void ResourceFetcher::didFinishLoading(Resource* resource,
-                                       double finishTime,
-                                       DidFinishLoadingReason finishReason) {
-  network_instrumentation::endResourceLoad(
-      resource->identifier(), network_instrumentation::RequestOutcome::Success);
-  DCHECK(resource);
-  const int64_t encodedDataLength = resource->response().encodedDataLength();
+void ResourceFetcher::handleLoadCompletion(Resource* resource) {
+  context().didLoadResource(resource);
 
-  // When loading a multipart resource, make the loader non-block when finishing
-  // loading the first part.
-  if (finishReason == DidFinishFirstPartInMultipart)
-    moveResourceLoaderToNonBlocking(resource->loader());
-  else
-    removeResourceLoader(resource->loader());
-  DCHECK(!m_loaders.contains(resource->loader()));
-  DCHECK(finishReason == DidFinishFirstPartInMultipart ||
-         !m_nonBlockingLoaders.contains(resource->loader()));
+  if (resource->isImage() &&
+      toImageResource(resource)->shouldReloadBrokenPlaceholder()) {
+    toImageResource(resource)->reloadIfLoFiOrPlaceholder(this);
+  }
+}
+
+void ResourceFetcher::handleLoaderFinish(Resource* resource,
+                                         double finishTime,
+                                         LoaderFinishType type) {
+  DCHECK(resource);
+
+  ResourceLoader* loader = resource->loader();
+  if (type == DidFinishFirstPartInMultipart) {
+    // When loading a multipart resource, make the loader non-block when
+    // finishing loading the first part.
+    moveResourceLoaderToNonBlocking(loader);
+  } else {
+    removeResourceLoader(loader);
+    DCHECK(!m_nonBlockingLoaders.contains(loader));
+  }
+  DCHECK(!m_loaders.contains(loader));
+
+  const int64_t encodedDataLength = resource->response().encodedDataLength();
 
   if (resource->getType() == Resource::MainResource) {
     DCHECK(m_navigationTimingInfo);
@@ -1190,126 +1164,40 @@
       // them.
       info->addFinalTransferSize(encodedDataLength == -1 ? 0
                                                          : encodedDataLength);
+
       if (resource->options().requestInitiatorContext == DocumentContext)
         context().addResourceTiming(*info);
       resource->reportResourceTimingToClients(*info);
     }
   }
+
   context().dispatchDidFinishLoading(resource->identifier(), finishTime,
                                      encodedDataLength);
-  if (finishReason == DidFinishLoading)
-    resource->finish(finishTime);
-  context().didLoadResource(resource);
 
-  if (resource->isImage() &&
-      toImageResource(resource)->shouldReloadBrokenPlaceholder()) {
-    toImageResource(resource)->reloadIfLoFiOrPlaceholder(this);
-  }
+  if (type == DidFinishLoading)
+    resource->finish(finishTime);
+
+  handleLoadCompletion(resource);
 }
 
-void ResourceFetcher::didFailLoading(Resource* resource,
-                                     const ResourceError& error) {
-  network_instrumentation::endResourceLoad(
-      resource->identifier(), network_instrumentation::RequestOutcome::Fail);
+void ResourceFetcher::handleLoaderError(Resource* resource,
+                                        const ResourceError& error) {
+  DCHECK(resource);
+
   removeResourceLoader(resource->loader());
-  m_resourceTimingInfoMap.take(const_cast<Resource*>(resource));
+
+  m_resourceTimingInfoMap.take(resource);
+
   bool isInternalRequest = resource->options().initiatorInfo.name ==
                            FetchInitiatorTypeNames::internal;
+
   context().dispatchDidFail(resource->identifier(), error,
                             resource->response().encodedDataLength(),
                             isInternalRequest);
+
   resource->error(error);
-  context().didLoadResource(resource);
 
-  if (resource->isImage() &&
-      toImageResource(resource)->shouldReloadBrokenPlaceholder()) {
-    toImageResource(resource)->reloadIfLoFiOrPlaceholder(this);
-  }
-}
-
-void ResourceFetcher::didReceiveResponse(
-    Resource* resource,
-    const ResourceResponse& response,
-    std::unique_ptr<WebDataConsumerHandle> handle) {
-  if (response.wasFetchedViaServiceWorker()) {
-    if (resource->options().corsEnabled == IsCORSEnabled &&
-        response.wasFallbackRequiredByServiceWorker()) {
-      ResourceRequest request = resource->lastResourceRequest();
-      DCHECK_EQ(request.skipServiceWorker(),
-                WebURLRequest::SkipServiceWorker::None);
-      // This code handles the case when a regular controlling service worker
-      // doesn't handle a cross origin request. When this happens we still want
-      // to give foreign fetch a chance to handle the request, so only skip the
-      // controlling service worker for the fallback request. This is currently
-      // safe because of http://crbug.com/604084 the
-      // wasFallbackRequiredByServiceWorker flag is never set when foreign fetch
-      // handled a request.
-      if (!context().shouldLoadNewResource(resource->getType())) {
-        // Cancel the request if we should not trigger a reload now.
-        resource->loader()->didFail(
-            ResourceError::cancelledError(response.url()));
-        return;
-      }
-      request.setSkipServiceWorker(
-          WebURLRequest::SkipServiceWorker::Controlling);
-      resource->loader()->restart(request, context().loadingTaskRunner(),
-                                  context().defersLoading());
-      return;
-    }
-
-    // If the response is fetched via ServiceWorker, the original URL of the
-    // response could be different from the URL of the request. We check the URL
-    // not to load the resources which are forbidden by the page CSP.
-    // https://w3c.github.io/webappsec-csp/#should-block-response
-    const KURL& originalURL = response.originalURLViaServiceWorker();
-    if (!originalURL.isEmpty()) {
-      ResourceRequestBlockedReason blockedReason = context().allowResponse(
-          resource->getType(), resource->resourceRequest(), originalURL,
-          resource->options());
-      if (blockedReason != ResourceRequestBlockedReason::None) {
-        resource->loader()->didFail(
-            ResourceError::cancelledDueToAccessCheckError(originalURL,
-                                                          blockedReason));
-        return;
-      }
-    }
-  } else if (resource->options().corsEnabled == IsCORSEnabled) {
-    ResourceRequestBlockedReason blockedReason =
-        canAccessResponse(resource, response);
-    if (blockedReason != ResourceRequestBlockedReason::None) {
-      resource->loader()->didFail(ResourceError::cancelledDueToAccessCheckError(
-          response.url(), blockedReason));
-      return;
-    }
-  }
-
-  context().dispatchDidReceiveResponse(
-      resource->identifier(), response, resource->resourceRequest().frameType(),
-      resource->resourceRequest().requestContext(), resource);
-  resource->responseReceived(response, std::move(handle));
-  if (resource->loader() && response.httpStatusCode() >= 400 &&
-      !resource->shouldIgnoreHTTPStatusCodeErrors()) {
-    resource->loader()->didFail(ResourceError::cancelledError(response.url()));
-  }
-}
-
-void ResourceFetcher::didReceiveData(const Resource* resource,
-                                     const char* data,
-                                     int dataLength) {
-  context().dispatchDidReceiveData(resource->identifier(), data, dataLength);
-}
-
-void ResourceFetcher::didReceiveTransferSizeUpdate(const Resource* resource,
-                                                   int transferSizeDiff) {
-  context().dispatchDidReceiveEncodedData(resource->identifier(),
-                                          transferSizeDiff);
-}
-
-void ResourceFetcher::didDownloadData(const Resource* resource,
-                                      int dataLength,
-                                      int encodedDataLength) {
-  context().dispatchDidDownloadData(resource->identifier(), dataLength,
-                                    encodedDataLength);
+  handleLoadCompletion(resource);
 }
 
 void ResourceFetcher::moveResourceLoaderToNonBlocking(ResourceLoader* loader) {
@@ -1329,11 +1217,13 @@
   }
 
   ResourceRequest request(resource->resourceRequest());
-  willSendRequest(resource->identifier(), request, ResourceResponse(),
-                  resource->options());
+  context().dispatchWillSendRequest(resource->identifier(), request,
+                                    ResourceResponse(),
+                                    resource->options().initiatorInfo);
 
   // TODO(shaochuan): Saving modified ResourceRequest back to |resource|, remove
-  // once willSendRequest() takes const ResourceRequest. crbug.com/632580
+  // once dispatchWillSendRequest() takes const ResourceRequest.
+  // crbug.com/632580
   resource->setResourceRequest(request);
 
   // Resource requests from suborigins should not be intercepted by the service
@@ -1354,8 +1244,7 @@
   resource->setFetcherSecurityOrigin(sourceOrigin);
 
   loader->activateCacheAwareLoadingIfNeeded(request);
-  loader->start(request, context().loadingTaskRunner(),
-                context().defersLoading());
+  loader->start(request);
   return true;
 }
 
@@ -1393,78 +1282,6 @@
     loader->setDefersLoading(defers);
 }
 
-bool ResourceFetcher::defersLoading() const {
-  return context().defersLoading();
-}
-
-static bool isManualRedirectFetchRequest(const ResourceRequest& request) {
-  return request.fetchRedirectMode() ==
-             WebURLRequest::FetchRedirectModeManual &&
-         request.requestContext() == WebURLRequest::RequestContextFetch;
-}
-
-ResourceRequestBlockedReason ResourceFetcher::willFollowRedirect(
-    Resource* resource,
-    ResourceRequest& newRequest,
-    const ResourceResponse& redirectResponse) {
-  if (!isManualRedirectFetchRequest(resource->resourceRequest())) {
-    ResourceRequestBlockedReason blockedReason =
-        context().canRequest(resource->getType(), newRequest, newRequest.url(),
-                             resource->options(), resource->isUnusedPreload(),
-                             FetchRequest::UseDefaultOriginRestrictionForType);
-    if (blockedReason != ResourceRequestBlockedReason::None)
-      return blockedReason;
-    if (resource->options().corsEnabled == IsCORSEnabled) {
-      RefPtr<SecurityOrigin> sourceOrigin = resource->options().securityOrigin;
-      if (!sourceOrigin.get())
-        sourceOrigin = context().getSecurityOrigin();
-
-      String errorMessage;
-      StoredCredentials withCredentials =
-          resource->lastResourceRequest().allowStoredCredentials()
-              ? AllowStoredCredentials
-              : DoNotAllowStoredCredentials;
-      if (!CrossOriginAccessControl::handleRedirect(
-              sourceOrigin, newRequest, redirectResponse, withCredentials,
-              resource->mutableOptions(), errorMessage)) {
-        resource->setCORSFailed();
-        context().addConsoleMessage(errorMessage);
-        return ResourceRequestBlockedReason::Other;
-      }
-    }
-    if (resource->getType() == Resource::Image &&
-        shouldDeferImageLoad(newRequest.url())) {
-      return ResourceRequestBlockedReason::Other;
-    }
-  }
-
-  ResourceTimingInfoMap::iterator it = m_resourceTimingInfoMap.find(resource);
-  if (it != m_resourceTimingInfoMap.end()) {
-    bool crossOrigin = IsCrossOrigin(redirectResponse.url(), newRequest.url());
-    it->value->addRedirect(redirectResponse, crossOrigin);
-  }
-
-  if (resource->getType() == Resource::MainResource) {
-    DCHECK(m_navigationTimingInfo);
-    bool crossOrigin = IsCrossOrigin(redirectResponse.url(), newRequest.url());
-    m_navigationTimingInfo->addRedirect(redirectResponse, crossOrigin);
-  }
-
-  newRequest.setAllowStoredCredentials(resource->options().allowCredentials ==
-                                       AllowStoredCredentials);
-  willSendRequest(resource->identifier(), newRequest, redirectResponse,
-                  resource->options());
-  return ResourceRequestBlockedReason::None;
-}
-
-void ResourceFetcher::willSendRequest(unsigned long identifier,
-                                      ResourceRequest& newRequest,
-                                      const ResourceResponse& redirectResponse,
-                                      const ResourceLoaderOptions& options) {
-  context().dispatchWillSendRequest(identifier, newRequest, redirectResponse,
-                                    options.initiatorInfo);
-}
-
 void ResourceFetcher::updateAllImageResourcePriorities() {
   TRACE_EVENT0(
       "blink",
diff --git a/third_party/WebKit/Source/core/fetch/ResourceFetcher.h b/third_party/WebKit/Source/core/fetch/ResourceFetcher.h
index 08972762..c4b2df5 100644
--- a/third_party/WebKit/Source/core/fetch/ResourceFetcher.h
+++ b/third_party/WebKit/Source/core/fetch/ResourceFetcher.h
@@ -115,24 +115,13 @@
   void stopFetching();
   bool isFetching() const;
 
-  ResourceRequestBlockedReason willFollowRedirect(Resource*,
-                                                  ResourceRequest&,
-                                                  const ResourceResponse&);
-  enum DidFinishLoadingReason {
-    DidFinishLoading,
-    DidFinishFirstPartInMultipart
-  };
-  void didFinishLoading(Resource*,
-                        double finishTime,
-                        DidFinishLoadingReason);
-  void didFailLoading(Resource*, const ResourceError&);
-  void didReceiveResponse(Resource*,
-                          const ResourceResponse&,
-                          std::unique_ptr<WebDataConsumerHandle>);
-  void didReceiveData(const Resource*, const char* data, int dataLength);
-  void didReceiveTransferSizeUpdate(const Resource*, int transferSizeDiff);
-  void didDownloadData(const Resource*, int dataLength, int encodedDataLength);
-  bool defersLoading() const;
+  bool shouldDeferImageLoad(const KURL&) const;
+
+  void recordResourceTimingOnRedirect(Resource*, const ResourceResponse&, bool);
+
+  enum LoaderFinishType { DidFinishLoading, DidFinishFirstPartInMultipart };
+  void handleLoaderFinish(Resource*, double finishTime, LoaderFinishType);
+  void handleLoaderError(Resource*, const ResourceError&);
   bool isControlledByServiceWorker() const;
 
   enum ResourceLoadStartType {
@@ -196,17 +185,11 @@
   void moveCachedNonBlockingResourceToBlocking(Resource*, const FetchRequest&);
   void moveResourceLoaderToNonBlocking(ResourceLoader*);
   void removeResourceLoader(ResourceLoader*);
+  void handleLoadCompletion(Resource*);
 
   void initializeResourceRequest(ResourceRequest&,
                                  Resource::Type,
                                  FetchRequest::DeferOption);
-  void willSendRequest(unsigned long identifier,
-                       ResourceRequest&,
-                       const ResourceResponse&,
-                       const ResourceLoaderOptions&);
-  ResourceRequestBlockedReason canAccessResponse(Resource*,
-                                                 const ResourceResponse&) const;
-
   void requestLoadStarted(unsigned long identifier,
                           Resource*,
                           const FetchRequest&,
@@ -214,7 +197,6 @@
                           bool isStaticData = false);
 
   bool resourceNeedsLoad(Resource*, const FetchRequest&, RevalidationPolicy);
-  bool shouldDeferImageLoad(const KURL&) const;
 
   void resourceTimingReportTimerFired(TimerBase*);
 
diff --git a/third_party/WebKit/Source/core/fetch/ResourceFetcherTest.cpp b/third_party/WebKit/Source/core/fetch/ResourceFetcherTest.cpp
index 83c82de..a0ecc90 100644
--- a/third_party/WebKit/Source/core/fetch/ResourceFetcherTest.cpp
+++ b/third_party/WebKit/Source/core/fetch/ResourceFetcherTest.cpp
@@ -36,7 +36,7 @@
 #include "core/fetch/ImageResource.h"
 #include "core/fetch/MemoryCache.h"
 #include "core/fetch/MockFetchContext.h"
-#include "core/fetch/MockResourceClients.h"
+#include "core/fetch/MockResourceClient.h"
 #include "core/fetch/RawResource.h"
 #include "core/fetch/ResourceLoader.h"
 #include "platform/WebTaskRunner.h"
@@ -178,8 +178,7 @@
   long long redirectEncodedDataLength = 123;
   redirectResponse.setEncodedDataLength(redirectEncodedDataLength);
   ResourceRequest redirectResourceRequest(url);
-  fetcher->willFollowRedirect(resource, redirectResourceRequest,
-                              redirectResponse);
+  fetcher->recordResourceTimingOnRedirect(resource, redirectResponse, false);
   EXPECT_EQ(navigationTimingInfo->transferSize(),
             encodedDataLength + redirectEncodedDataLength);
   Platform::current()->getURLLoaderMockFactory()->unregisterURL(url);
diff --git a/third_party/WebKit/Source/core/fetch/ResourceLoader.cpp b/third_party/WebKit/Source/core/fetch/ResourceLoader.cpp
index bc0dc11..16f8e70 100644
--- a/third_party/WebKit/Source/core/fetch/ResourceLoader.cpp
+++ b/third_party/WebKit/Source/core/fetch/ResourceLoader.cpp
@@ -29,11 +29,14 @@
 
 #include "core/fetch/ResourceLoader.h"
 
+#include "core/fetch/CrossOriginAccessControl.h"
+#include "core/fetch/FetchContext.h"
 #include "core/fetch/Resource.h"
 #include "core/fetch/ResourceFetcher.h"
 #include "platform/SharedBuffer.h"
 #include "platform/exported/WrappedResourceRequest.h"
 #include "platform/exported/WrappedResourceResponse.h"
+#include "platform/network/NetworkInstrumentation.h"
 #include "platform/network/ResourceError.h"
 #include "public/platform/Platform.h"
 #include "public/platform/WebCachePolicy.h"
@@ -59,6 +62,7 @@
       m_isCacheAwareLoadingActivated(false) {
   DCHECK(m_resource);
   DCHECK(m_fetcher);
+
   m_resource->setLoader(this);
 }
 
@@ -71,20 +75,19 @@
   visitor->trace(m_resource);
 }
 
-void ResourceLoader::start(const ResourceRequest& request,
-                           WebTaskRunner* loadingTaskRunner,
-                           bool defersLoading) {
+void ResourceLoader::start(const ResourceRequest& request) {
   DCHECK(!m_loader);
+
   if (m_resource->options().synchronousPolicy == RequestSynchronously &&
-      defersLoading) {
+      context().defersLoading()) {
     cancel();
     return;
   }
 
   m_loader = WTF::wrapUnique(Platform::current()->createURLLoader());
   DCHECK(m_loader);
-  m_loader->setDefersLoading(defersLoading);
-  m_loader->setLoadingTaskRunner(loadingTaskRunner);
+  m_loader->setDefersLoading(context().defersLoading());
+  m_loader->setLoadingTaskRunner(context().loadingTaskRunner());
 
   if (m_isCacheAwareLoadingActivated) {
     // Override cache policy for cache-aware loading. If this request fails, a
@@ -102,22 +105,17 @@
     m_loader->loadAsynchronously(WrappedResourceRequest(request), this);
 }
 
-void ResourceLoader::restart(const ResourceRequest& request,
-                             WebTaskRunner* loadingTaskRunner,
-                             bool defersLoading) {
+void ResourceLoader::restart(const ResourceRequest& request) {
   CHECK_EQ(m_resource->options().synchronousPolicy, RequestAsynchronously);
+
   m_loader.reset();
-  start(request, loadingTaskRunner, defersLoading);
+  start(request);
 }
 
 void ResourceLoader::setDefersLoading(bool defers) {
   DCHECK(m_loader);
-  m_loader->setDefersLoading(defers);
-}
 
-void ResourceLoader::didDownloadData(int length, int encodedDataLength) {
-  m_fetcher->didDownloadData(m_resource.get(), length, encodedDataLength);
-  m_resource->didDownloadData(length);
+  m_loader->setDefersLoading(defers);
 }
 
 void ResourceLoader::didChangePriority(ResourceLoadPriority loadPriority,
@@ -129,7 +127,7 @@
 }
 
 void ResourceLoader::cancel() {
-  didFail(
+  handleError(
       ResourceError::cancelledError(m_resource->lastResourceRequest().url()));
 }
 
@@ -138,10 +136,15 @@
     ResourceRequestBlockedReason blockedReason) {
   m_resource->willNotFollowRedirect();
 
-  if (m_loader) {
-    didFail(
+  if (m_loader)
+    handleError(
         ResourceError::cancelledDueToAccessCheckError(newURL, blockedReason));
-  }
+}
+
+static bool isManualRedirectFetchRequest(const ResourceRequest& request) {
+  return request.fetchRedirectMode() ==
+             WebURLRequest::FetchRedirectModeManual &&
+         request.requestContext() == WebURLRequest::RequestContextFetch;
 }
 
 bool ResourceLoader::willFollowRedirect(
@@ -152,7 +155,7 @@
 
   if (m_isCacheAwareLoadingActivated) {
     // Fail as cache miss if cached response is a redirect.
-    didFail(
+    handleError(
         ResourceError::cacheMissError(m_resource->lastResourceRequest().url()));
     return false;
   }
@@ -160,18 +163,63 @@
   ResourceRequest& newRequest(passedNewRequest.toMutableResourceRequest());
   const ResourceResponse& redirectResponse(
       passedRedirectResponse.toResourceResponse());
+
   newRequest.setRedirectStatus(
       ResourceRequest::RedirectStatus::FollowedRedirect);
 
   const KURL originalURL = newRequest.url();
 
-  ResourceRequestBlockedReason blockedReason = m_fetcher->willFollowRedirect(
-      m_resource.get(), newRequest, redirectResponse);
-  if (blockedReason != ResourceRequestBlockedReason::None) {
-    cancelForRedirectAccessCheckError(newRequest.url(), blockedReason);
-    return false;
+  if (!isManualRedirectFetchRequest(m_resource->resourceRequest())) {
+    ResourceRequestBlockedReason blockedReason = context().canRequest(
+        m_resource->getType(), newRequest, newRequest.url(),
+        m_resource->options(), m_resource->isUnusedPreload(),
+        FetchRequest::UseDefaultOriginRestrictionForType);
+    if (blockedReason != ResourceRequestBlockedReason::None) {
+      cancelForRedirectAccessCheckError(newRequest.url(), blockedReason);
+      return false;
+    }
+
+    if (m_resource->options().corsEnabled == IsCORSEnabled) {
+      RefPtr<SecurityOrigin> sourceOrigin =
+          m_resource->options().securityOrigin;
+      if (!sourceOrigin.get())
+        sourceOrigin = context().getSecurityOrigin();
+
+      String errorMessage;
+      StoredCredentials withCredentials =
+          m_resource->lastResourceRequest().allowStoredCredentials()
+              ? AllowStoredCredentials
+              : DoNotAllowStoredCredentials;
+      if (!CrossOriginAccessControl::handleRedirect(
+              sourceOrigin, newRequest, redirectResponse, withCredentials,
+              m_resource->mutableOptions(), errorMessage)) {
+        m_resource->setCORSFailed();
+        context().addConsoleMessage(errorMessage);
+        cancelForRedirectAccessCheckError(newRequest.url(),
+                                          ResourceRequestBlockedReason::Other);
+        return false;
+      }
+    }
+    if (m_resource->getType() == Resource::Image &&
+        m_fetcher->shouldDeferImageLoad(newRequest.url())) {
+      cancelForRedirectAccessCheckError(newRequest.url(),
+                                        ResourceRequestBlockedReason::Other);
+      return false;
+    }
   }
 
+  bool crossOrigin = !SecurityOrigin::areSameSchemeHostPort(
+      redirectResponse.url(), newRequest.url());
+  m_fetcher->recordResourceTimingOnRedirect(m_resource.get(), redirectResponse,
+                                            crossOrigin);
+
+  newRequest.setAllowStoredCredentials(m_resource->options().allowCredentials ==
+                                       AllowStoredCredentials);
+
+  context().dispatchWillSendRequest(m_resource->identifier(), newRequest,
+                                    redirectResponse,
+                                    m_resource->options().initiatorInfo);
+
   // ResourceFetcher::willFollowRedirect() may rewrite the URL to
   // something else not for rejecting redirect but for other reasons.
   // E.g. WebFrameTestClient::willSendRequest() and
@@ -202,33 +250,155 @@
   m_resource->didSendData(bytesSent, totalBytesToBeSent);
 }
 
+FetchContext& ResourceLoader::context() const {
+  return m_fetcher->context();
+}
+
+ResourceRequestBlockedReason ResourceLoader::canAccessResponse(
+    Resource* resource,
+    const ResourceResponse& response) const {
+  // Redirects can change the response URL different from one of request.
+  bool forPreload = resource->isUnusedPreload();
+  ResourceRequestBlockedReason blockedReason =
+      context().canRequest(resource->getType(), resource->resourceRequest(),
+                           response.url(), resource->options(), forPreload,
+                           FetchRequest::UseDefaultOriginRestrictionForType);
+  if (blockedReason != ResourceRequestBlockedReason::None)
+    return blockedReason;
+
+  SecurityOrigin* sourceOrigin = resource->options().securityOrigin.get();
+  if (!sourceOrigin)
+    sourceOrigin = context().getSecurityOrigin();
+
+  if (sourceOrigin->canRequestNoSuborigin(response.url()))
+    return ResourceRequestBlockedReason::None;
+
+  // Use the original response instead of the 304 response for a successful
+  // revaldiation.
+  const ResourceResponse& responseForAccessControl =
+      (resource->isCacheValidator() && response.httpStatusCode() == 304)
+          ? resource->response()
+          : response;
+  String errorDescription;
+  if (!passesAccessControlCheck(
+          responseForAccessControl, resource->options().allowCredentials,
+          sourceOrigin, errorDescription,
+          resource->lastResourceRequest().requestContext())) {
+    resource->setCORSFailed();
+    if (!forPreload) {
+      String resourceType = Resource::resourceTypeToString(
+          resource->getType(), resource->options().initiatorInfo);
+      context().addConsoleMessage(
+          "Access to " + resourceType + " at '" + response.url().getString() +
+          "' from origin '" + sourceOrigin->toString() +
+          "' has been blocked by CORS policy: " + errorDescription);
+    }
+    return ResourceRequestBlockedReason::Other;
+  }
+  return ResourceRequestBlockedReason::None;
+}
+
 void ResourceLoader::didReceiveResponse(
-    const WebURLResponse& response,
+    const WebURLResponse& webURLResponse,
     std::unique_ptr<WebDataConsumerHandle> handle) {
-  DCHECK(!response.isNull());
-  m_fetcher->didReceiveResponse(m_resource.get(), response.toResourceResponse(),
-                                std::move(handle));
+  DCHECK(!webURLResponse.isNull());
+
+  const ResourceResponse& response = webURLResponse.toResourceResponse();
+
+  if (response.wasFetchedViaServiceWorker()) {
+    if (m_resource->options().corsEnabled == IsCORSEnabled &&
+        response.wasFallbackRequiredByServiceWorker()) {
+      ResourceRequest request = m_resource->lastResourceRequest();
+      DCHECK_EQ(request.skipServiceWorker(),
+                WebURLRequest::SkipServiceWorker::None);
+      // This code handles the case when a regular controlling service worker
+      // doesn't handle a cross origin request. When this happens we still want
+      // to give foreign fetch a chance to handle the request, so only skip the
+      // controlling service worker for the fallback request. This is currently
+      // safe because of http://crbug.com/604084 the
+      // wasFallbackRequiredByServiceWorker flag is never set when foreign fetch
+      // handled a request.
+      if (!context().shouldLoadNewResource(m_resource->getType())) {
+        // Cancel the request if we should not trigger a reload now.
+        handleError(ResourceError::cancelledError(response.url()));
+        return;
+      }
+      request.setSkipServiceWorker(
+          WebURLRequest::SkipServiceWorker::Controlling);
+      restart(request);
+      return;
+    }
+
+    // If the response is fetched via ServiceWorker, the original URL of the
+    // response could be different from the URL of the request. We check the URL
+    // not to load the resources which are forbidden by the page CSP.
+    // https://w3c.github.io/webappsec-csp/#should-block-response
+    const KURL& originalURL = response.originalURLViaServiceWorker();
+    if (!originalURL.isEmpty()) {
+      ResourceRequestBlockedReason blockedReason = context().allowResponse(
+          m_resource->getType(), m_resource->resourceRequest(), originalURL,
+          m_resource->options());
+      if (blockedReason != ResourceRequestBlockedReason::None) {
+        handleError(ResourceError::cancelledDueToAccessCheckError(
+            originalURL, blockedReason));
+        return;
+      }
+    }
+  } else if (m_resource->options().corsEnabled == IsCORSEnabled) {
+    ResourceRequestBlockedReason blockedReason =
+        canAccessResponse(m_resource, response);
+    if (blockedReason != ResourceRequestBlockedReason::None) {
+      handleError(ResourceError::cancelledDueToAccessCheckError(response.url(),
+                                                                blockedReason));
+      return;
+    }
+  }
+
+  context().dispatchDidReceiveResponse(
+      m_resource->identifier(), response,
+      m_resource->resourceRequest().frameType(),
+      m_resource->resourceRequest().requestContext(), m_resource);
+
+  m_resource->responseReceived(response, std::move(handle));
+  if (!m_resource->loader())
+    return;
+
+  if (response.httpStatusCode() >= 400 &&
+      !m_resource->shouldIgnoreHTTPStatusCodeErrors())
+    handleError(ResourceError::cancelledError(response.url()));
 }
 
 void ResourceLoader::didReceiveResponse(const WebURLResponse& response) {
   didReceiveResponse(response, nullptr);
 }
 
+void ResourceLoader::didDownloadData(int length, int encodedDataLength) {
+  context().dispatchDidDownloadData(m_resource->identifier(), length,
+                                    encodedDataLength);
+  m_resource->didDownloadData(length);
+}
+
 void ResourceLoader::didReceiveData(const char* data, int length) {
   CHECK_GE(length, 0);
-  m_fetcher->didReceiveData(m_resource.get(), data, length);
+
+  context().dispatchDidReceiveData(m_resource->identifier(), data, length);
   m_resource->addToDecodedBodyLength(length);
   m_resource->appendData(data, length);
 }
 
 void ResourceLoader::didReceiveTransferSizeUpdate(int transferSizeDiff) {
   DCHECK_GT(transferSizeDiff, 0);
-  m_fetcher->didReceiveTransferSizeUpdate(m_resource.get(), transferSizeDiff);
+  context().dispatchDidReceiveEncodedData(m_resource->identifier(),
+                                          transferSizeDiff);
 }
 
 void ResourceLoader::didFinishLoadingFirstPartInMultipart() {
-  m_fetcher->didFinishLoading(m_resource.get(), 0,
-                              ResourceFetcher::DidFinishFirstPartInMultipart);
+  network_instrumentation::endResourceLoad(
+      m_resource->identifier(),
+      network_instrumentation::RequestOutcome::Success);
+
+  m_fetcher->handleLoaderFinish(m_resource.get(), 0,
+                                ResourceFetcher::DidFinishFirstPartInMultipart);
 }
 
 void ResourceLoader::didFinishLoading(double finishTime,
@@ -236,9 +406,15 @@
                                       int64_t encodedBodyLength) {
   m_resource->setEncodedDataLength(encodedDataLength);
   m_resource->addToEncodedBodyLength(encodedBodyLength);
+
   m_loader.reset();
-  m_fetcher->didFinishLoading(m_resource.get(), finishTime,
-                              ResourceFetcher::DidFinishLoading);
+
+  network_instrumentation::endResourceLoad(
+      m_resource->identifier(),
+      network_instrumentation::RequestOutcome::Success);
+
+  m_fetcher->handleLoaderFinish(m_resource.get(), finishTime,
+                                ResourceFetcher::DidFinishLoading);
 }
 
 void ResourceLoader::didFail(const WebURLError& error,
@@ -246,22 +422,24 @@
                              int64_t encodedBodyLength) {
   m_resource->setEncodedDataLength(encodedDataLength);
   m_resource->addToEncodedBodyLength(encodedBodyLength);
-  didFail(error);
+  handleError(error);
 }
 
-void ResourceLoader::didFail(const ResourceError& error) {
+void ResourceLoader::handleError(const ResourceError& error) {
   if (m_isCacheAwareLoadingActivated && error.isCacheMiss() &&
-      m_fetcher->context().shouldLoadNewResource(m_resource->getType())) {
+      context().shouldLoadNewResource(m_resource->getType())) {
     m_resource->willReloadAfterDiskCacheMiss();
     m_isCacheAwareLoadingActivated = false;
-    restart(m_resource->resourceRequest(),
-            m_fetcher->context().loadingTaskRunner(),
-            m_fetcher->context().defersLoading());
+    restart(m_resource->resourceRequest());
     return;
   }
 
   m_loader.reset();
-  m_fetcher->didFailLoading(m_resource.get(), error);
+
+  network_instrumentation::endResourceLoad(
+      m_resource->identifier(), network_instrumentation::RequestOutcome::Fail);
+
+  m_fetcher->handleLoaderError(m_resource.get(), error);
 }
 
 void ResourceLoader::requestSynchronously(const ResourceRequest& request) {
@@ -297,7 +475,8 @@
   // empty buffer is a noop in most cases, but is destructive in the case of
   // a 304, where it will overwrite the cached data we should be reusing.
   if (dataOut.size()) {
-    m_fetcher->didReceiveData(m_resource.get(), dataOut.data(), dataOut.size());
+    context().dispatchDidReceiveData(m_resource->identifier(), dataOut.data(),
+                                     dataOut.size());
     m_resource->setResourceBuffer(dataOut);
   }
   didFinishLoading(monotonicallyIncreasingTime(), encodedDataLength,
diff --git a/third_party/WebKit/Source/core/fetch/ResourceLoader.h b/third_party/WebKit/Source/core/fetch/ResourceLoader.h
index ff45ab1..b836a46 100644
--- a/third_party/WebKit/Source/core/fetch/ResourceLoader.h
+++ b/third_party/WebKit/Source/core/fetch/ResourceLoader.h
@@ -39,10 +39,15 @@
 
 namespace blink {
 
+class FetchContext;
 class Resource;
 class ResourceError;
 class ResourceFetcher;
 
+// A ResourceLoader is created for each Resource by the ResourceFetcher when it
+// needs to load the specified resource. A ResourceLoader creates a
+// WebURLLoader and loads the resource using it. Any per-load logic should be
+// implemented in this class basically.
 class CORE_EXPORT ResourceLoader final
     : public GarbageCollectedFinalized<ResourceLoader>,
       protected WebURLLoaderClient {
@@ -51,16 +56,7 @@
   ~ResourceLoader() override;
   DECLARE_TRACE();
 
-  void start(const ResourceRequest&,
-             WebTaskRunner* loadingTaskRunner,
-             bool defersLoading);
-
-  // This method is currently only used for service worker fallback request and
-  // cache-aware loading, other users should be careful not to break
-  // ResourceLoader state.
-  void restart(const ResourceRequest&,
-               WebTaskRunner* loadingTaskRunner,
-               bool defersLoading);
+  void start(const ResourceRequest&);
 
   void cancel();
 
@@ -105,14 +101,23 @@
   void didFail(const WebURLError&,
                int64_t encodedDataLength,
                int64_t encodedBodyLength) override;
+  void handleError(const ResourceError&);
 
   void didFinishLoadingFirstPartInMultipart();
-  void didFail(const ResourceError&);
 
  private:
   // Assumes ResourceFetcher and Resource are non-null.
   ResourceLoader(ResourceFetcher*, Resource*);
 
+  // This method is currently only used for service worker fallback request and
+  // cache-aware loading, other users should be careful not to break
+  // ResourceLoader state.
+  void restart(const ResourceRequest&);
+
+  FetchContext& context() const;
+  ResourceRequestBlockedReason canAccessResponse(Resource*,
+                                                 const ResourceResponse&) const;
+
   void cancelForRedirectAccessCheckError(const KURL&,
                                          ResourceRequestBlockedReason);
   void requestSynchronously(const ResourceRequest&);
diff --git a/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp b/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
index b90acdd..5b164de 100644
--- a/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
@@ -146,7 +146,8 @@
 }
 
 void HTMLCanvasElement::dispose() {
-  releasePlaceholderFrame();
+  if (placeholderFrame())
+    releasePlaceholderFrame();
 
   if (m_context) {
     m_context->detachCanvas();
diff --git a/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp
index da950b94..18245a2 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp
@@ -1576,6 +1576,9 @@
           .setNodeValue(nodeValue)
           .build();
 
+  if (node->isSVGElement())
+    value->setIsSVG(true);
+
   bool forcePushChildren = false;
   if (node->isElementNode()) {
     Element* element = toElement(node);
diff --git a/third_party/WebKit/Source/core/inspector/browser_protocol.json b/third_party/WebKit/Source/core/inspector/browser_protocol.json
index 482a8db..25d702a 100644
--- a/third_party/WebKit/Source/core/inspector/browser_protocol.json
+++ b/third_party/WebKit/Source/core/inspector/browser_protocol.json
@@ -2024,7 +2024,8 @@
                     { "name": "templateContent", "$ref": "Node", "optional": true, "description": "Content document fragment for template elements.", "experimental": true },
                     { "name": "pseudoElements", "type": "array", "items": { "$ref": "Node" }, "optional": true, "description": "Pseudo elements associated with this node.", "experimental": true },
                     { "name": "importedDocument", "$ref": "Node", "optional": true, "description": "Import document for the HTMLImport links." },
-                    { "name": "distributedNodes", "type": "array", "items": { "$ref": "BackendNode" }, "optional": true, "description": "Distributed nodes for given insertion point.", "experimental": true }
+                    { "name": "distributedNodes", "type": "array", "items": { "$ref": "BackendNode" }, "optional": true, "description": "Distributed nodes for given insertion point.", "experimental": true },
+                    { "name": "isSVG", "type": "boolean", "optional": true, "description": "Whether the node is SVG.", "experimental": true }
                 ],
                 "description": "DOM interaction is implemented in terms of mirror objects that represent the actual DOM nodes. DOMNode is a base node mirror type."
             },
diff --git a/third_party/WebKit/Source/core/loader/BUILD.gn b/third_party/WebKit/Source/core/loader/BUILD.gn
index 33c258a..e543f34 100644
--- a/third_party/WebKit/Source/core/loader/BUILD.gn
+++ b/third_party/WebKit/Source/core/loader/BUILD.gn
@@ -17,6 +17,8 @@
     "EmptyClients.cpp",
     "EmptyClients.h",
     "FormSubmission.cpp",
+    "FrameClientHintsPreferencesContext.cpp",
+    "FrameClientHintsPreferencesContext.h",
     "FrameFetchContext.cpp",
     "FrameFetchContext.h",
     "FrameLoadRequest.cpp",
diff --git a/third_party/WebKit/Source/core/loader/FrameClientHintsPreferencesContext.cpp b/third_party/WebKit/Source/core/loader/FrameClientHintsPreferencesContext.cpp
new file mode 100644
index 0000000..69ad42a
--- /dev/null
+++ b/third_party/WebKit/Source/core/loader/FrameClientHintsPreferencesContext.cpp
@@ -0,0 +1,27 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "core/loader/FrameClientHintsPreferencesContext.h"
+
+#include "core/frame/UseCounter.h"
+
+namespace blink {
+
+FrameClientHintsPreferencesContext::FrameClientHintsPreferencesContext(
+    Frame* frame)
+    : m_frame(frame) {}
+
+void FrameClientHintsPreferencesContext::countClientHintsDPR() {
+  UseCounter::count(m_frame, UseCounter::ClientHintsDPR);
+}
+
+void FrameClientHintsPreferencesContext::countClientHintsResourceWidth() {
+  UseCounter::count(m_frame, UseCounter::ClientHintsResourceWidth);
+}
+
+void FrameClientHintsPreferencesContext::countClientHintsViewportWidth() {
+  UseCounter::count(m_frame, UseCounter::ClientHintsViewportWidth);
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/core/loader/FrameClientHintsPreferencesContext.h b/third_party/WebKit/Source/core/loader/FrameClientHintsPreferencesContext.h
new file mode 100644
index 0000000..260842af
--- /dev/null
+++ b/third_party/WebKit/Source/core/loader/FrameClientHintsPreferencesContext.h
@@ -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.
+
+#ifndef FrameClientHintsPreferencesContext_h
+#define FrameClientHintsPreferencesContext_h
+
+#include "core/fetch/ClientHintsPreferences.h"
+#include "core/frame/Frame.h"
+#include "platform/heap/Persistent.h"
+#include "wtf/Allocator.h"
+
+namespace blink {
+
+class FrameClientHintsPreferencesContext final
+    : public ClientHintsPreferences::Context {
+  STACK_ALLOCATED();
+
+ public:
+  explicit FrameClientHintsPreferencesContext(Frame*);
+
+  void countClientHintsDPR() override;
+  void countClientHintsResourceWidth() override;
+  void countClientHintsViewportWidth() override;
+
+ private:
+  Member<Frame> m_frame;
+};
+
+}  // namespace blink
+
+#endif  // FrameClientHintsPreferencesContext_h
diff --git a/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp b/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
index 54838d53..baf159b 100644
--- a/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
+++ b/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
@@ -41,6 +41,7 @@
 #include "core/frame/LocalDOMWindow.h"
 #include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
+#include "core/frame/UseCounter.h"
 #include "core/html/HTMLFrameOwnerElement.h"
 #include "core/html/imports/HTMLImportsController.h"
 #include "core/inspector/ConsoleMessage.h"
@@ -49,6 +50,7 @@
 #include "core/inspector/InspectorNetworkAgent.h"
 #include "core/inspector/InspectorTraceEvents.h"
 #include "core/loader/DocumentLoader.h"
+#include "core/loader/FrameClientHintsPreferencesContext.h"
 #include "core/loader/FrameLoader.h"
 #include "core/loader/FrameLoaderClient.h"
 #include "core/loader/MixedContentChecker.h"
@@ -952,18 +954,6 @@
       ->archive();
 }
 
-void FrameFetchContext::countClientHintsDPR() {
-  UseCounter::count(frame(), UseCounter::ClientHintsDPR);
-}
-
-void FrameFetchContext::countClientHintsResourceWidth() {
-  UseCounter::count(frame(), UseCounter::ClientHintsResourceWidth);
-}
-
-void FrameFetchContext::countClientHintsViewportWidth() {
-  UseCounter::count(frame(), UseCounter::ClientHintsViewportWidth);
-}
-
 ResourceLoadPriority FrameFetchContext::modifyPriorityForExperiments(
     ResourceLoadPriority priority) {
   // If Settings is null, we can't verify any experiments are in force.
@@ -996,12 +986,10 @@
   if (m_documentLoader &&
       m_documentLoader ==
           m_documentLoader->frame()->loader().provisionalDocumentLoader()) {
-    ResourceFetcher* fetcher = nullptr;
-    if (frame()->document())
-      fetcher = frame()->document()->fetcher();
+    FrameClientHintsPreferencesContext hintsContext(frame());
     m_documentLoader->clientHintsPreferences()
         .updateFromAcceptClientHintsHeader(
-            response.httpHeaderField(HTTPNames::Accept_CH), fetcher);
+            response.httpHeaderField(HTTPNames::Accept_CH), &hintsContext);
     // When response is received with a provisional docloader, the resource
     // haven't committed yet, and we cannot load resources, only preconnect.
     resourceLoadingPolicy = LinkLoader::DoNotLoadResources;
diff --git a/third_party/WebKit/Source/core/loader/FrameFetchContext.h b/third_party/WebKit/Source/core/loader/FrameFetchContext.h
index 3df4081..549f301 100644
--- a/third_party/WebKit/Source/core/loader/FrameFetchContext.h
+++ b/third_party/WebKit/Source/core/loader/FrameFetchContext.h
@@ -152,10 +152,6 @@
   ResourceLoadPriority modifyPriorityForExperiments(
       ResourceLoadPriority) override;
 
-  void countClientHintsDPR() override;
-  void countClientHintsResourceWidth() override;
-  void countClientHintsViewportWidth() override;
-
   WebTaskRunner* loadingTaskRunner() const override;
 
   DECLARE_VIRTUAL_TRACE();
diff --git a/third_party/WebKit/Source/core/loader/HttpEquiv.cpp b/third_party/WebKit/Source/core/loader/HttpEquiv.cpp
index f85dfdb..5d01e5e 100644
--- a/third_party/WebKit/Source/core/loader/HttpEquiv.cpp
+++ b/third_party/WebKit/Source/core/loader/HttpEquiv.cpp
@@ -8,10 +8,12 @@
 #include "core/dom/ScriptableDocumentParser.h"
 #include "core/dom/StyleEngine.h"
 #include "core/fetch/ClientHintsPreferences.h"
+#include "core/frame/LocalFrame.h"
 #include "core/frame/UseCounter.h"
 #include "core/frame/csp/ContentSecurityPolicy.h"
 #include "core/inspector/ConsoleMessage.h"
 #include "core/loader/DocumentLoader.h"
+#include "core/loader/FrameClientHintsPreferencesContext.h"
 #include "core/origin_trials/OriginTrialContext.h"
 #include "platform/HTTPNames.h"
 #include "platform/network/HTTPParsers.h"
@@ -87,8 +89,9 @@
     return;
 
   UseCounter::count(document, UseCounter::ClientHintsMetaAcceptCH);
+  FrameClientHintsPreferencesContext hintsContext(document.frame());
   document.clientHintsPreferences().updateFromAcceptClientHintsHeader(
-      content, document.fetcher());
+      content, &hintsContext);
 }
 
 void HttpEquiv::processHttpEquivDefaultStyle(Document& document,
diff --git a/third_party/WebKit/Source/core/loader/resource/FontResourceTest.cpp b/third_party/WebKit/Source/core/loader/resource/FontResourceTest.cpp
index 2eaa28ef..b30d380 100644
--- a/third_party/WebKit/Source/core/loader/resource/FontResourceTest.cpp
+++ b/third_party/WebKit/Source/core/loader/resource/FontResourceTest.cpp
@@ -8,6 +8,7 @@
 #include "core/fetch/FetchRequest.h"
 #include "core/fetch/MemoryCache.h"
 #include "core/fetch/MockFetchContext.h"
+#include "core/fetch/MockResourceClient.h"
 #include "core/fetch/ResourceFetcher.h"
 #include "core/fetch/ResourceLoader.h"
 #include "core/loader/resource/MockFontResourceClient.h"
@@ -112,7 +113,7 @@
   EXPECT_FALSE(client->fontLoadShortLimitExceededCalled());
 
   // Fail first request as disk cache miss.
-  resource->loader()->didFail(ResourceError::cacheMissError(url));
+  resource->loader()->handleError(ResourceError::cacheMissError(url));
 
   // Once cache miss error returns, previously blocked callbacks should be
   // called immediately.
diff --git a/third_party/WebKit/Source/core/page/FocusController.cpp b/third_party/WebKit/Source/core/page/FocusController.cpp
index 4e0e692..de9da9165 100644
--- a/third_party/WebKit/Source/core/page/FocusController.cpp
+++ b/third_party/WebKit/Source/core/page/FocusController.cpp
@@ -76,13 +76,28 @@
   STACK_ALLOCATED();
 
  public:
-  Element* currentElement() const;
-  void setCurrentElement(Element*);
-  void moveToNext();
-  void moveToPrevious();
-  void moveToFirst();
-  void moveToLast();
+  // Searches through the given tree scope, starting from start element, for
+  // the next/previous selectable element that comes after/before start element.
+  // The order followed is as specified in the HTML spec[1], which is elements
+  // with tab indexes first (from lowest to highest), and then elements without
+  // tab indexes (in document order).  The search algorithm also conforms the
+  // Shadow DOM spec[2], which inserts sequence in a shadow tree into its host.
+  //
+  // @param start The element from which to start searching. The element after
+  //              this will be focused. May be null.
+  // @return The focus element that comes after/before start element.
+  //
+  // [1]
+  // https://html.spec.whatwg.org/multipage/interaction.html#sequential-focus-navigation
+  // [2] https://w3c.github.io/webcomponents/spec/shadow/#focus-navigation
+  Element* findFocusableElement(WebFocusType type) {
+    return (type == WebFocusTypeForward) ? nextFocusableElement()
+                                         : previousFocusableElement();
+  }
+
+  Element* currentElement() const { return m_current; }
   Element* owner() const;
+
   static ScopedFocusNavigation createFor(const Element&);
   static ScopedFocusNavigation createForDocument(Document&);
   static ScopedFocusNavigation ownedByNonFocusableFocusScopeOwner(Element&);
@@ -98,6 +113,19 @@
  private:
   ScopedFocusNavigation(TreeScope&, const Element*);
   ScopedFocusNavigation(HTMLSlotElement&, const Element*);
+
+  Element* findElementWithExactTabIndex(int tabIndex, WebFocusType);
+  Element* nextElementWithGreaterTabIndex(int tabIndex);
+  Element* previousElementWithLowerTabIndex(int tabIndex);
+  Element* nextFocusableElement();
+  Element* previousFocusableElement();
+
+  void setCurrentElement(Element* element) { m_current = element; }
+  void moveToNext();
+  void moveToPrevious();
+  void moveToFirst();
+  void moveToLast();
+
   Member<ContainerNode> m_rootNode;
   Member<HTMLSlotElement> m_rootSlot;
   Member<Element> m_current;
@@ -117,14 +145,6 @@
       m_current(const_cast<Element*>(current)),
       m_slotFallbackTraversal(slot.assignedNodes().isEmpty()) {}
 
-Element* ScopedFocusNavigation::currentElement() const {
-  return m_current;
-}
-
-void ScopedFocusNavigation::setCurrentElement(Element* element) {
-  m_current = element;
-}
-
 void ScopedFocusNavigation::moveToNext() {
   DCHECK(m_current);
   if (m_rootSlot) {
@@ -410,27 +430,25 @@
          isNonFocusableFocusScopeOwner(element);
 }
 
-Element* findElementWithExactTabIndex(ScopedFocusNavigation& scope,
-                                      int tabIndex,
-                                      WebFocusType type) {
+Element* ScopedFocusNavigation::findElementWithExactTabIndex(
+    int tabIndex,
+    WebFocusType type) {
   // Search is inclusive of start
-  for (; scope.currentElement(); type == WebFocusTypeForward
-                                     ? scope.moveToNext()
-                                     : scope.moveToPrevious()) {
-    Element* current = scope.currentElement();
+  for (; currentElement();
+       type == WebFocusTypeForward ? moveToNext() : moveToPrevious()) {
+    Element* current = currentElement();
     if (shouldVisit(*current) && adjustedTabIndex(*current) == tabIndex)
       return current;
   }
   return nullptr;
 }
 
-Element* nextElementWithGreaterTabIndex(ScopedFocusNavigation& scope,
-                                        int tabIndex) {
+Element* ScopedFocusNavigation::nextElementWithGreaterTabIndex(int tabIndex) {
   // Search is inclusive of start
   int winningTabIndex = std::numeric_limits<int>::max();
   Element* winner = nullptr;
-  for (; scope.currentElement(); scope.moveToNext()) {
-    Element* current = scope.currentElement();
+  for (; currentElement(); moveToNext()) {
+    Element* current = currentElement();
     int currentTabIndex = adjustedTabIndex(*current);
     if (shouldVisit(*current) && currentTabIndex > tabIndex) {
       if (!winner || currentTabIndex < winningTabIndex) {
@@ -439,16 +457,16 @@
       }
     }
   }
+  setCurrentElement(winner);
   return winner;
 }
 
-Element* previousElementWithLowerTabIndex(ScopedFocusNavigation& scope,
-                                          int tabIndex) {
+Element* ScopedFocusNavigation::previousElementWithLowerTabIndex(int tabIndex) {
   // Search is inclusive of start
   int winningTabIndex = 0;
   Element* winner = nullptr;
-  for (; scope.currentElement(); scope.moveToPrevious()) {
-    Element* current = scope.currentElement();
+  for (; currentElement(); moveToPrevious()) {
+    Element* current = currentElement();
     int currentTabIndex = adjustedTabIndex(*current);
     if (shouldVisit(*current) && currentTabIndex < tabIndex &&
         currentTabIndex > winningTabIndex) {
@@ -456,27 +474,28 @@
       winningTabIndex = currentTabIndex;
     }
   }
+  setCurrentElement(winner);
   return winner;
 }
 
-Element* nextFocusableElement(ScopedFocusNavigation& scope) {
-  Element* current = scope.currentElement();
+Element* ScopedFocusNavigation::nextFocusableElement() {
+  Element* current = currentElement();
   if (current) {
     int tabIndex = adjustedTabIndex(*current);
     // If an element is excluded from the normal tabbing cycle, the next
     // focusable element is determined by tree order.
     if (tabIndex < 0) {
-      for (scope.moveToNext(); scope.currentElement(); scope.moveToNext()) {
-        current = scope.currentElement();
+      for (moveToNext(); currentElement(); moveToNext()) {
+        current = currentElement();
         if (shouldVisit(*current) && adjustedTabIndex(*current) >= 0)
           return current;
       }
     } else {
       // First try to find an element with the same tabindex as start that comes
       // after start in the scope.
-      scope.moveToNext();
-      if (Element* winner = findElementWithExactTabIndex(scope, tabIndex,
-                                                         WebFocusTypeForward))
+      moveToNext();
+      if (Element* winner =
+              findElementWithExactTabIndex(tabIndex, WebFocusTypeForward))
         return winner;
     }
     if (!tabIndex) {
@@ -490,43 +509,43 @@
   // 1) has the lowest tabindex that is higher than start's tabindex (or 0, if
   //    start is null), and
   // 2) comes first in the scope, if there's a tie.
-  scope.moveToFirst();
+  moveToFirst();
   if (Element* winner = nextElementWithGreaterTabIndex(
-          scope, current ? adjustedTabIndex(*current) : 0)) {
+          current ? adjustedTabIndex(*current) : 0)) {
     return winner;
   }
 
   // There are no elements with a tabindex greater than start's tabindex,
   // so find the first element with a tabindex of 0.
-  scope.moveToFirst();
-  return findElementWithExactTabIndex(scope, 0, WebFocusTypeForward);
+  moveToFirst();
+  return findElementWithExactTabIndex(0, WebFocusTypeForward);
 }
 
-Element* previousFocusableElement(ScopedFocusNavigation& scope) {
+Element* ScopedFocusNavigation::previousFocusableElement() {
   // First try to find the last element in the scope that comes before start and
   // has the same tabindex as start.  If start is null, find the last element in
   // the scope with a tabindex of 0.
   int tabIndex;
-  Element* current = scope.currentElement();
+  Element* current = currentElement();
   if (current) {
-    scope.moveToPrevious();
+    moveToPrevious();
     tabIndex = adjustedTabIndex(*current);
   } else {
-    scope.moveToLast();
+    moveToLast();
     tabIndex = 0;
   }
 
   // However, if an element is excluded from the normal tabbing cycle, the
   // previous focusable element is determined by tree order
   if (tabIndex < 0) {
-    for (; scope.currentElement(); scope.moveToPrevious()) {
-      current = scope.currentElement();
+    for (; currentElement(); moveToPrevious()) {
+      current = currentElement();
       if (shouldVisit(*current) && adjustedTabIndex(*current) >= 0)
         return current;
     }
   } else {
     if (Element* winner =
-            findElementWithExactTabIndex(scope, tabIndex, WebFocusTypeBackward))
+            findElementWithExactTabIndex(tabIndex, WebFocusTypeBackward))
       return winner;
   }
 
@@ -536,36 +555,13 @@
   //    and
   // 2) comes last in the scope, if there's a tie.
   tabIndex = (current && tabIndex) ? tabIndex : std::numeric_limits<int>::max();
-  scope.moveToLast();
-  return previousElementWithLowerTabIndex(scope, tabIndex);
-}
-
-// Searches through the given tree scope, starting from start element, for the
-// next/previous selectable element that comes after/before start element.
-// The order followed is as specified in the HTML spec[1], which is elements
-// with tab indexes first (from lowest to highest), and then elements without
-// tab indexes (in document order).  The search algorithm also conforms the
-// Shadow DOM spec[2], which inserts sequence in a shadow tree into its host.
-//
-// @param start The element from which to start searching. The element after
-//              this will be focused. May be null.
-// @return The focus element that comes after/before start element.
-//
-// [1]
-// https://html.spec.whatwg.org/multipage/interaction.html#sequential-focus-navigation
-// [2] https://w3c.github.io/webcomponents/spec/shadow/#focus-navigation
-inline Element* findFocusableElementInternal(WebFocusType type,
-                                             ScopedFocusNavigation& scope) {
-  Element* found = (type == WebFocusTypeForward)
-                       ? nextFocusableElement(scope)
-                       : previousFocusableElement(scope);
-  return found;
+  moveToLast();
+  return previousElementWithLowerTabIndex(tabIndex);
 }
 
 Element* findFocusableElementRecursivelyForward(ScopedFocusNavigation& scope) {
   // Starting element is exclusive.
-  Element* found = findFocusableElementInternal(WebFocusTypeForward, scope);
-  while (found) {
+  while (Element* found = scope.findFocusableElement(WebFocusTypeForward)) {
     if (isShadowHostDelegatesFocus(*found)) {
       // If tabindex is positive, find focusable element inside its shadow tree.
       if (found->tabIndex() >= 0 &&
@@ -577,7 +573,6 @@
           return foundInInnerFocusScope;
       }
       // Skip to the next element in the same scope.
-      found = findFocusableElementInternal(WebFocusTypeForward, scope);
       continue;
     }
     if (!isNonFocusableFocusScopeOwner(*found))
@@ -591,18 +586,13 @@
     if (Element* foundInInnerFocusScope =
             findFocusableElementRecursivelyForward(innerScope))
       return foundInInnerFocusScope;
-
-    scope.setCurrentElement(found);
-    found = findFocusableElementInternal(WebFocusTypeForward, scope);
   }
   return nullptr;
 }
 
 Element* findFocusableElementRecursivelyBackward(ScopedFocusNavigation& scope) {
   // Starting element is exclusive.
-  Element* found = findFocusableElementInternal(WebFocusTypeBackward, scope);
-
-  while (found) {
+  while (Element* found = scope.findFocusableElement(WebFocusTypeBackward)) {
     // Now |found| is on a focusable shadow host.
     // Find inside shadow backwards. If any focusable element is found, return
     // it, otherwise return the host itself.
@@ -613,39 +603,29 @@
           findFocusableElementRecursivelyBackward(innerScope);
       if (foundInInnerFocusScope)
         return foundInInnerFocusScope;
-      if (isShadowHostDelegatesFocus(*found)) {
-        found = findFocusableElementInternal(WebFocusTypeBackward, scope);
+      if (isShadowHostDelegatesFocus(*found))
         continue;
-      }
       return found;
     }
 
     // If delegatesFocus is true and tabindex is negative, skip the whole shadow
     // tree under the shadow host.
-    if (isShadowHostDelegatesFocus(*found) && found->tabIndex() < 0) {
-      found = findFocusableElementInternal(WebFocusTypeBackward, scope);
+    if (isShadowHostDelegatesFocus(*found) && found->tabIndex() < 0)
       continue;
-    }
 
-    // Now |found| is on a non focusable scope owner (either shadow host or
-    // <shadow> or slot).  Find focusable element in descendant scope. If not
-    // found, find next focusable element within the current scope.
+    // Now |found| is on a non focusable scope owner (a shadow host, a <shadow>
+    // or a slot).  Find focusable element in descendant scope. If not found,
+    // find the next focusable element within the current scope.
     if (isNonFocusableFocusScopeOwner(*found)) {
       ScopedFocusNavigation innerScope =
           ScopedFocusNavigation::ownedByNonFocusableFocusScopeOwner(*found);
-      Element* foundInInnerFocusScope =
-          findFocusableElementRecursivelyBackward(innerScope);
-
-      if (foundInInnerFocusScope)
+      if (Element* foundInInnerFocusScope =
+              findFocusableElementRecursivelyBackward(innerScope))
         return foundInInnerFocusScope;
-      found = findFocusableElementInternal(WebFocusTypeBackward, scope);
       continue;
     }
     if (!isShadowHostDelegatesFocus(*found))
       return found;
-
-    scope.setCurrentElement(found);
-    found = findFocusableElementInternal(WebFocusTypeBackward, scope);
   }
   return nullptr;
 }
diff --git a/third_party/WebKit/Source/devtools/front_end/bindings/BlackboxManager.js b/third_party/WebKit/Source/devtools/front_end/bindings/BlackboxManager.js
index 6b9e290..4f17a9f3 100644
--- a/third_party/WebKit/Source/devtools/front_end/bindings/BlackboxManager.js
+++ b/third_party/WebKit/Source/devtools/front_end/bindings/BlackboxManager.js
@@ -304,7 +304,7 @@
    * @param {!Common.Event} event
    */
   _globalObjectCleared(event) {
-    var debuggerModel = /** @type {!SDK.DebuggerModel} */ (event.target);
+    var debuggerModel = /** @type {!SDK.DebuggerModel} */ (event.data);
     this._debuggerModelData.delete(debuggerModel);
     this._isBlackboxedURLCache.clear();
   }
diff --git a/third_party/WebKit/Source/devtools/front_end/bindings/BreakpointManager.js b/third_party/WebKit/Source/devtools/front_end/bindings/BreakpointManager.js
index 40223e10..606c1ef 100644
--- a/third_party/WebKit/Source/devtools/front_end/bindings/BreakpointManager.js
+++ b/third_party/WebKit/Source/devtools/front_end/bindings/BreakpointManager.js
@@ -173,7 +173,7 @@
    * @param {!Common.Event} event
    */
   _uiSourceCodeMappingChanged(event) {
-    var uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.target);
+    var uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data.uiSourceCode);
     var isIdentity = /** @type {boolean} */ (event.data.isIdentity);
     var target = /** @type {!SDK.Target} */ (event.data.target);
     if (isIdentity)
diff --git a/third_party/WebKit/Source/devtools/front_end/bindings/CompilerScriptMapping.js b/third_party/WebKit/Source/devtools/front_end/bindings/CompilerScriptMapping.js
index c1aeb93b..b17e718 100644
--- a/third_party/WebKit/Source/devtools/front_end/bindings/CompilerScriptMapping.js
+++ b/third_party/WebKit/Source/devtools/front_end/bindings/CompilerScriptMapping.js
@@ -183,7 +183,7 @@
    * @param {!Common.Event} event
    */
   _sourceMapURLAdded(event) {
-    var script = /** @type {!SDK.Script} */ (event.target);
+    var script = /** @type {!SDK.Script} */ (event.data);
     if (!script.sourceMapURL)
       return;
     this._processScript(script);
diff --git a/third_party/WebKit/Source/devtools/front_end/bindings/DebuggerWorkspaceBinding.js b/third_party/WebKit/Source/devtools/front_end/bindings/DebuggerWorkspaceBinding.js
index 5d5080c9..1f9c3bca 100644
--- a/third_party/WebKit/Source/devtools/front_end/bindings/DebuggerWorkspaceBinding.js
+++ b/third_party/WebKit/Source/devtools/front_end/bindings/DebuggerWorkspaceBinding.js
@@ -261,7 +261,7 @@
    * @param {!Common.Event} event
    */
   _globalObjectCleared(event) {
-    var debuggerModel = /** @type {!SDK.DebuggerModel} */ (event.target);
+    var debuggerModel = /** @type {!SDK.DebuggerModel} */ (event.data);
     this._reset(debuggerModel.target());
   }
 
@@ -322,7 +322,7 @@
    * @param {!Common.Event} event
    */
   _debuggerResumed(event) {
-    var debuggerModel = /** @type {!SDK.DebuggerModel} */ (event.target);
+    var debuggerModel = /** @type {!SDK.DebuggerModel} */ (event.data);
     this._reset(debuggerModel.target());
   }
 };
@@ -395,9 +395,11 @@
     else
       this._uiSourceCodeToSourceMapping.remove(uiSourceCode);
 
-    uiSourceCode.dispatchEventToListeners(
-        Workspace.UISourceCode.Events.SourceMappingChanged,
-        {target: this._debuggerModel.target(), isIdentity: sourceMapping ? sourceMapping.isIdentity() : false});
+    uiSourceCode.dispatchEventToListeners(Workspace.UISourceCode.Events.SourceMappingChanged, {
+      uiSourceCode: uiSourceCode,
+      target: this._debuggerModel.target(),
+      isIdentity: sourceMapping ? sourceMapping.isIdentity() : false
+    });
   }
 
   /**
diff --git a/third_party/WebKit/Source/devtools/front_end/bindings/NetworkProject.js b/third_party/WebKit/Source/devtools/front_end/bindings/NetworkProject.js
index e75c0456..054424f5 100644
--- a/third_party/WebKit/Source/devtools/front_end/bindings/NetworkProject.js
+++ b/third_party/WebKit/Source/devtools/front_end/bindings/NetworkProject.js
@@ -262,6 +262,8 @@
     var header = /** @type {!SDK.CSSStyleSheetHeader} */ (event.data);
     if (header.isInline && !header.hasSourceURL && header.origin !== 'inspector')
       return;
+    if (!header.resourceURL())
+      return;
 
     var originalContentProvider = header.originalContentProvider();
     var uiSourceCode = this._createFile(originalContentProvider, SDK.ResourceTreeFrame.fromStyleSheet(header), false);
diff --git a/third_party/WebKit/Source/devtools/front_end/bindings/ResourceScriptMapping.js b/third_party/WebKit/Source/devtools/front_end/bindings/ResourceScriptMapping.js
index bb311be..578d420 100644
--- a/third_party/WebKit/Source/devtools/front_end/bindings/ResourceScriptMapping.js
+++ b/third_party/WebKit/Source/devtools/front_end/bindings/ResourceScriptMapping.js
@@ -313,6 +313,9 @@
     this._update();
   }
 
+  /**
+   * @param {!Common.Event} event
+   */
   _workingCopyCommitted(event) {
     if (this._uiSourceCode.project().canSetFileContent())
       return;
diff --git a/third_party/WebKit/Source/devtools/front_end/common/Object.js b/third_party/WebKit/Source/devtools/front_end/common/Object.js
index fe01dd3..c25bcda9 100644
--- a/third_party/WebKit/Source/devtools/front_end/common/Object.js
+++ b/third_party/WebKit/Source/devtools/front_end/common/Object.js
@@ -92,7 +92,7 @@
     if (!this._listeners || !this._listeners.has(eventType))
       return;
 
-    var event = new Common.Event(this, eventData);
+    var event = new Common.Event(eventData);
     var listeners = this._listeners.get(eventType).slice(0);
     for (var i = 0; i < listeners.length; ++i)
       listeners[i].listener.call(listeners[i].thisObject, event);
@@ -104,11 +104,9 @@
  */
 Common.Event = class {
   /**
-   * @param {!Common.EventTarget} target
    * @param {*=} data
    */
-  constructor(target, data) {
-    this.target = target;
+  constructor(data) {
     this.data = data;
   }
 };
diff --git a/third_party/WebKit/Source/devtools/front_end/console/ConsoleView.js b/third_party/WebKit/Source/devtools/front_end/console/ConsoleView.js
index 6f0d6aa..326d8305 100644
--- a/third_party/WebKit/Source/devtools/front_end/console/ConsoleView.js
+++ b/third_party/WebKit/Source/devtools/front_end/console/ConsoleView.js
@@ -209,7 +209,7 @@
    * @param {!Common.Event} event
    */
   _onResourceTreeModelLoaded(event) {
-    var resourceTreeModel = event.target;
+    var resourceTreeModel = /** @type {!SDK.ResourceTreeModel} */ (event.data);
     if (resourceTreeModel.target() !== SDK.targetManager.mainTarget())
       return;
     SDK.targetManager.removeModelListener(
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/ElementsPanel.js b/third_party/WebKit/Source/devtools/front_end/elements/ElementsPanel.js
index 9f4768e..00ed351 100644
--- a/third_party/WebKit/Source/devtools/front_end/elements/ElementsPanel.js
+++ b/third_party/WebKit/Source/devtools/front_end/elements/ElementsPanel.js
@@ -362,8 +362,8 @@
    * @param {!Common.Event} event
    */
   _documentUpdatedEvent(event) {
-    this._documentUpdated(
-        /** @type {!SDK.DOMModel} */ (event.target), /** @type {?SDK.DOMDocument} */ (event.data));
+    var domModel = /** @type {!SDK.DOMModel} */ (event.data);
+    this._documentUpdated(domModel, domModel.existingDocument());
   }
 
   /**
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/ElementsTreeOutline.js b/third_party/WebKit/Source/devtools/front_end/elements/ElementsTreeOutline.js
index 7c309e9..d26ca6d1 100644
--- a/third_party/WebKit/Source/devtools/front_end/elements/ElementsTreeOutline.js
+++ b/third_party/WebKit/Source/devtools/front_end/elements/ElementsTreeOutline.js
@@ -1040,7 +1040,8 @@
    * @param {!Common.Event} event
    */
   _documentUpdated(event) {
-    var inspectedRootDocument = event.data;
+    var domModel = /** @type {!SDK.DOMModel} */ (event.data);
+    var inspectedRootDocument = domModel.existingDocument();
 
     this._reset();
 
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/StylesSidebarPane.js b/third_party/WebKit/Source/devtools/front_end/elements/StylesSidebarPane.js
index 2f41c11..e934696 100644
--- a/third_party/WebKit/Source/devtools/front_end/elements/StylesSidebarPane.js
+++ b/third_party/WebKit/Source/devtools/front_end/elements/StylesSidebarPane.js
@@ -2323,8 +2323,15 @@
       selectElement.parentElement.scrollIntoViewIfNeeded(false);
 
     var applyItemCallback = !isEditingName ? this._applyFreeFlowStyleTextEdit.bind(this) : undefined;
-    var cssCompletions = isEditingName ? SDK.cssMetadata().allProperties() :
-                                         SDK.cssMetadata().propertyValues(this.nameElement.textContent);
+    var cssCompletions = [];
+    if (isEditingName) {
+      cssCompletions = SDK.cssMetadata().allProperties();
+      cssCompletions =
+          cssCompletions.filter(property => SDK.cssMetadata().isSVGProperty(property) === this.node().isSVGNode());
+    } else {
+      cssCompletions = SDK.cssMetadata().propertyValues(this.nameElement.textContent);
+    }
+
     this._prompt = new Elements.StylesSidebarPane.CSSPropertyPrompt(cssCompletions, this, isEditingName);
     this._prompt.setAutocompletionTimeout(0);
     if (applyItemCallback) {
diff --git a/third_party/WebKit/Source/devtools/front_end/emulation/DeviceModeToolbar.js b/third_party/WebKit/Source/devtools/front_end/emulation/DeviceModeToolbar.js
index b7dec58..54fa80e 100644
--- a/third_party/WebKit/Source/devtools/front_end/emulation/DeviceModeToolbar.js
+++ b/third_party/WebKit/Source/devtools/front_end/emulation/DeviceModeToolbar.js
@@ -452,8 +452,8 @@
     }
 
     var contextMenu = new UI.ContextMenu(
-        /** @type {!Event} */ (event.data), false, event.target.element.totalOffsetLeft(),
-        event.target.element.totalOffsetTop() + event.target.element.offsetHeight);
+        /** @type {!Event} */ (event.data), false, this._modeButton.element.totalOffsetLeft(),
+        this._modeButton.element.totalOffsetTop() + this._modeButton.element.offsetHeight);
     addOrientation(Emulation.EmulatedDevice.Vertical, Common.UIString('Portrait'));
     addOrientation(Emulation.EmulatedDevice.Horizontal, Common.UIString('Landscape'));
     contextMenu.show();
diff --git a/third_party/WebKit/Source/devtools/front_end/emulation/TouchModel.js b/third_party/WebKit/Source/devtools/front_end/emulation/TouchModel.js
index 0cd5d3b..0d254dc 100644
--- a/third_party/WebKit/Source/devtools/front_end/emulation/TouchModel.js
+++ b/third_party/WebKit/Source/devtools/front_end/emulation/TouchModel.js
@@ -107,7 +107,7 @@
    * @param {!Common.Event} event
    */
   _inspectModeToggled(event) {
-    var domModel = /** @type {!SDK.DOMModel} */ (event.target);
+    var domModel = /** @type {!SDK.DOMModel} */ (event.data);
     this._applyToTarget(domModel.target());
   }
 
diff --git a/third_party/WebKit/Source/devtools/front_end/main/Main.js b/third_party/WebKit/Source/devtools/front_end/main/Main.js
index 5a877b01..f52322b 100644
--- a/third_party/WebKit/Source/devtools/front_end/main/Main.js
+++ b/third_party/WebKit/Source/devtools/front_end/main/Main.js
@@ -809,8 +809,8 @@
   _debuggerPaused(event) {
     SDK.targetManager.removeModelListener(
         SDK.DebuggerModel, SDK.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this);
-    var debuggerPausedDetails = /** @type {!SDK.DebuggerPausedDetails} */ (event.data);
-    var debuggerModel = /** @type {!SDK.DebuggerModel} */ (event.target);
+    var debuggerModel = /** @type {!SDK.DebuggerModel} */ (event.data);
+    var debuggerPausedDetails = debuggerModel.debuggerPausedDetails();
     UI.context.setFlavor(SDK.Target, debuggerModel.target());
     Common.Revealer.reveal(debuggerPausedDetails);
   }
diff --git a/third_party/WebKit/Source/devtools/front_end/main/OverlayController.js b/third_party/WebKit/Source/devtools/front_end/main/OverlayController.js
index 31acef8..deffeb6 100644
--- a/third_party/WebKit/Source/devtools/front_end/main/OverlayController.js
+++ b/third_party/WebKit/Source/devtools/front_end/main/OverlayController.js
@@ -28,7 +28,7 @@
    * @param {!Common.Event} event
    */
   _updateOverlay(event) {
-    this._updateTargetOverlay(/** @type {!SDK.DebuggerModel} */ (event.target));
+    this._updateTargetOverlay(/** @type {!SDK.DebuggerModel} */ (event.data));
   }
 
   /**
diff --git a/third_party/WebKit/Source/devtools/front_end/network/ResourceWebSocketFrameView.js b/third_party/WebKit/Source/devtools/front_end/network/ResourceWebSocketFrameView.js
index f7a634ae..ce9487f 100644
--- a/third_party/WebKit/Source/devtools/front_end/network/ResourceWebSocketFrameView.js
+++ b/third_party/WebKit/Source/devtools/front_end/network/ResourceWebSocketFrameView.js
@@ -108,7 +108,7 @@
    * @param {!Common.Event} event
    */
   _onFrameSelected(event) {
-    var selectedNode = /** @type {!Network.ResourceWebSocketFrameNode} */ (event.target.selectedNode);
+    var selectedNode = /** @type {!Network.ResourceWebSocketFrameNode} */ (event.data);
     this._currentSelectedNode = selectedNode;
     var contentProvider = selectedNode.contentProvider();
     contentProvider.requestContent().then(contentHandler.bind(this));
diff --git a/third_party/WebKit/Source/devtools/front_end/persistence/DefaultMapping.js b/third_party/WebKit/Source/devtools/front_end/persistence/DefaultMapping.js
index 13106fb..249ba4ca 100644
--- a/third_party/WebKit/Source/devtools/front_end/persistence/DefaultMapping.js
+++ b/third_party/WebKit/Source/devtools/front_end/persistence/DefaultMapping.js
@@ -127,7 +127,7 @@
    * @param {!Common.Event} event
    */
   _onFileSystemUISourceCodeRenamed(event) {
-    var uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.target);
+    var uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data);
     var binding = uiSourceCode[Persistence.DefaultMapping._binding];
     this._unbind(binding.network);
     this._bind(binding.network);
diff --git a/third_party/WebKit/Source/devtools/front_end/persistence/Persistence.js b/third_party/WebKit/Source/devtools/front_end/persistence/Persistence.js
index 53c33e57..d22a345 100644
--- a/third_party/WebKit/Source/devtools/front_end/persistence/Persistence.js
+++ b/third_party/WebKit/Source/devtools/front_end/persistence/Persistence.js
@@ -130,7 +130,7 @@
    * @param {!Common.Event} event
    */
   _onWorkingCopyChanged(event) {
-    var uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.target);
+    var uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data);
     var binding = uiSourceCode[Persistence.Persistence._binding];
     if (!binding || binding[Persistence.Persistence._muteWorkingCopy])
       return;
@@ -164,7 +164,7 @@
    * @param {!Common.Event} event
    */
   _onWorkingCopyCommitted(event) {
-    var uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.target);
+    var uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data.uiSourceCode);
     var binding = uiSourceCode[Persistence.Persistence._binding];
     if (!binding || binding[Persistence.Persistence._muteCommit])
       return;
diff --git a/third_party/WebKit/Source/devtools/front_end/profiler/HeapSnapshotView.js b/third_party/WebKit/Source/devtools/front_end/profiler/HeapSnapshotView.js
index 0c66cf8..a1cefb2 100644
--- a/third_party/WebKit/Source/devtools/front_end/profiler/HeapSnapshotView.js
+++ b/third_party/WebKit/Source/devtools/front_end/profiler/HeapSnapshotView.js
@@ -440,20 +440,29 @@
       this._dataGrid.populateContextMenu(contextMenu, event);
   }
 
+  /**
+   * @param {!Common.Event} event
+   */
   _selectionChanged(event) {
-    var selectedNode = event.target.selectedNode;
+    var selectedNode = /** @type {!Profiler.HeapSnapshotGridNode} */ (event.data);
     this._setSelectedNodeForDetailsView(selectedNode);
     this._inspectedObjectChanged(event);
   }
 
+  /**
+   * @param {!Common.Event} event
+   */
   _onSelectAllocationNode(event) {
-    var selectedNode = event.target.selectedNode;
+    var selectedNode = /** @type {!UI.DataGridNode} */ (event.data);
     this._constructorsDataGrid.setAllocationNodeId(selectedNode.allocationNodeId());
     this._setSelectedNodeForDetailsView(null);
   }
 
+  /**
+   * @param {!Common.Event} event
+   */
   _inspectedObjectChanged(event) {
-    var selectedNode = event.target.selectedNode;
+    var selectedNode = /** @type {!UI.DataGridNode} */ (event.data);
     var target = this._profile.target();
     if (target && selectedNode instanceof Profiler.HeapSnapshotGenericObjectNode)
       target.heapProfilerAgent().addInspectedHeapObject(String(selectedNode.snapshotNodeId));
diff --git a/third_party/WebKit/Source/devtools/front_end/resources/IndexedDBModel.js b/third_party/WebKit/Source/devtools/front_end/resources/IndexedDBModel.js
index 7fcfe518..b336ebf 100644
--- a/third_party/WebKit/Source/devtools/front_end/resources/IndexedDBModel.js
+++ b/third_party/WebKit/Source/devtools/front_end/resources/IndexedDBModel.js
@@ -272,7 +272,7 @@
    */
   _databaseAdded(securityOrigin, databaseName) {
     var databaseId = new Resources.IndexedDBModel.DatabaseId(securityOrigin, databaseName);
-    this.dispatchEventToListeners(Resources.IndexedDBModel.Events.DatabaseAdded, databaseId);
+    this.dispatchEventToListeners(Resources.IndexedDBModel.Events.DatabaseAdded, {model: this, databaseId: databaseId});
   }
 
   /**
@@ -281,7 +281,8 @@
    */
   _databaseRemoved(securityOrigin, databaseName) {
     var databaseId = new Resources.IndexedDBModel.DatabaseId(securityOrigin, databaseName);
-    this.dispatchEventToListeners(Resources.IndexedDBModel.Events.DatabaseRemoved, databaseId);
+    this.dispatchEventToListeners(
+        Resources.IndexedDBModel.Events.DatabaseRemoved, {model: this, databaseId: databaseId});
   }
 
   /**
@@ -341,7 +342,8 @@
         databaseModel.objectStores[objectStoreModel.name] = objectStoreModel;
       }
 
-      this.dispatchEventToListeners(Resources.IndexedDBModel.Events.DatabaseLoaded, databaseModel);
+      this.dispatchEventToListeners(
+          Resources.IndexedDBModel.Events.DatabaseLoaded, {model: this, database: databaseModel});
     }
 
     this._agent.requestDatabase(databaseId.securityOrigin, databaseId.name, callback.bind(this));
diff --git a/third_party/WebKit/Source/devtools/front_end/resources/ResourcesPanel.js b/third_party/WebKit/Source/devtools/front_end/resources/ResourcesPanel.js
index a54b1626..782d23d58 100644
--- a/third_party/WebKit/Source/devtools/front_end/resources/ResourcesPanel.js
+++ b/third_party/WebKit/Source/devtools/front_end/resources/ResourcesPanel.js
@@ -1264,8 +1264,8 @@
    * @param {!Common.Event} event
    */
   _cacheAdded(event) {
-    var cache = /** @type {!SDK.ServiceWorkerCacheModel.Cache} */ (event.data);
-    var model = /** @type {!SDK.ServiceWorkerCacheModel} */ (event.target);
+    var cache = /** @type {!SDK.ServiceWorkerCacheModel.Cache} */ (event.data.cache);
+    var model = /** @type {!SDK.ServiceWorkerCacheModel} */ (event.data.model);
     this._addCache(model, cache);
   }
 
@@ -1283,8 +1283,8 @@
    * @param {!Common.Event} event
    */
   _cacheRemoved(event) {
-    var cache = /** @type {!SDK.ServiceWorkerCacheModel.Cache} */ (event.data);
-    var model = /** @type {!SDK.ServiceWorkerCacheModel} */ (event.target);
+    var cache = /** @type {!SDK.ServiceWorkerCacheModel.Cache} */ (event.data.cache);
+    var model = /** @type {!SDK.ServiceWorkerCacheModel} */ (event.data.model);
 
     var swCacheTreeElement = this._cacheTreeElement(model, cache);
     if (!swCacheTreeElement)
@@ -1529,8 +1529,8 @@
    * @param {!Common.Event} event
    */
   _indexedDBAdded(event) {
-    var databaseId = /** @type {!Resources.IndexedDBModel.DatabaseId} */ (event.data);
-    var model = /** @type {!Resources.IndexedDBModel} */ (event.target);
+    var databaseId = /** @type {!Resources.IndexedDBModel.DatabaseId} */ (event.data.databaseId);
+    var model = /** @type {!Resources.IndexedDBModel} */ (event.data.model);
     this._addIndexedDB(model, databaseId);
   }
 
@@ -1549,8 +1549,8 @@
    * @param {!Common.Event} event
    */
   _indexedDBRemoved(event) {
-    var databaseId = /** @type {!Resources.IndexedDBModel.DatabaseId} */ (event.data);
-    var model = /** @type {!Resources.IndexedDBModel} */ (event.target);
+    var databaseId = /** @type {!Resources.IndexedDBModel.DatabaseId} */ (event.data.databaseId);
+    var model = /** @type {!Resources.IndexedDBModel} */ (event.data.model);
 
     var idbDatabaseTreeElement = this._idbDatabaseTreeElement(model, databaseId);
     if (!idbDatabaseTreeElement)
@@ -1565,8 +1565,8 @@
    * @param {!Common.Event} event
    */
   _indexedDBLoaded(event) {
-    var database = /** @type {!Resources.IndexedDBModel.Database} */ (event.data);
-    var model = /** @type {!Resources.IndexedDBModel} */ (event.target);
+    var database = /** @type {!Resources.IndexedDBModel.Database} */ (event.data.database);
+    var model = /** @type {!Resources.IndexedDBModel} */ (event.data.model);
 
     var idbDatabaseTreeElement = this._idbDatabaseTreeElement(model, database.databaseId);
     if (!idbDatabaseTreeElement)
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/CSSMetadata.js b/third_party/WebKit/Source/devtools/front_end/sdk/CSSMetadata.js
index c078efe..8add4b5 100644
--- a/third_party/WebKit/Source/devtools/front_end/sdk/CSSMetadata.js
+++ b/third_party/WebKit/Source/devtools/front_end/sdk/CSSMetadata.js
@@ -35,7 +35,7 @@
  */
 SDK.CSSMetadata = class {
   /**
-   * @param {!Array.<!{name: string, longhands: !Array.<string>}>} properties
+   * @param {!Array.<!{name: string, longhands: !Array.<string>, inherited: boolean, svg: boolean}>} properties
    */
   constructor(properties) {
     this._values = /** !Array.<string> */ ([]);
@@ -45,6 +45,8 @@
     this._shorthands = new Map();
     /** @type {!Set<string>} */
     this._inherited = new Set();
+    /** @type {!Set<string>} */
+    this._svgProperties = new Set();
     for (var i = 0; i < properties.length; ++i) {
       var property = properties[i];
       var propertyName = property.name;
@@ -54,6 +56,8 @@
 
       if (property.inherited)
         this._inherited.add(propertyName);
+      if (property.svg)
+        this._svgProperties.add(propertyName);
 
       var longhands = properties[i].longhands;
       if (longhands) {
@@ -81,6 +85,15 @@
   }
 
   /**
+   * @param {string} name
+   * @return {boolean}
+   */
+  isSVGProperty(name) {
+    name = name.toLowerCase();
+    return this._svgProperties.has(name);
+  }
+
+  /**
    * @param {string} shorthand
    * @return {?Array.<string>}
    */
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/DOMModel.js b/third_party/WebKit/Source/devtools/front_end/sdk/DOMModel.js
index b4a07c0..d95b8d5 100644
--- a/third_party/WebKit/Source/devtools/front_end/sdk/DOMModel.js
+++ b/third_party/WebKit/Source/devtools/front_end/sdk/DOMModel.js
@@ -75,6 +75,7 @@
     this._shadowRootType = payload.shadowRootType;
     this._frameOwnerFrameId = payload.frameId || null;
     this._xmlVersion = payload.xmlVersion;
+    this._isSVGNode = !!payload.isSVG;
 
     this._shadowRoots = [];
 
@@ -146,6 +147,13 @@
   }
 
   /**
+   * @return {boolean}
+   */
+  isSVGNode() {
+    return this._isSVGNode;
+  }
+
+  /**
    * @return {!SDK.DOMModel}
    */
   domModel() {
@@ -1370,7 +1378,7 @@
       this._document = new SDK.DOMDocument(this, payload);
     else
       this._document = null;
-    this.dispatchEventToListeners(SDK.DOMModel.Events.DocumentUpdated, this._document);
+    this.dispatchEventToListeners(SDK.DOMModel.Events.DocumentUpdated, this);
   }
 
   /**
@@ -1728,7 +1736,7 @@
      */
     function onDocumentAvailable() {
       this._inspectModeEnabled = mode !== Protocol.DOM.InspectMode.None;
-      this.dispatchEventToListeners(SDK.DOMModel.Events.InspectModeWillBeToggled, this._inspectModeEnabled);
+      this.dispatchEventToListeners(SDK.DOMModel.Events.InspectModeWillBeToggled, this);
       this._highlighter.setInspectMode(mode, this._buildHighlightConfig(), callback);
     }
     this.requestDocument(onDocumentAvailable.bind(this));
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerModel.js b/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerModel.js
index 4c0c485..177643a 100644
--- a/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerModel.js
+++ b/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerModel.js
@@ -104,7 +104,7 @@
     this._debuggerEnabled = true;
     this._pauseOnExceptionStateChanged();
     this.asyncStackTracesStateChanged();
-    this.dispatchEventToListeners(SDK.DebuggerModel.Events.DebuggerWasEnabled);
+    this.dispatchEventToListeners(SDK.DebuggerModel.Events.DebuggerWasEnabled, this);
   }
 
   /**
@@ -316,7 +316,7 @@
     this._setDebuggerPausedDetails(null);
     this._reset();
     // TODO(dgozman): move clients to ExecutionContextDestroyed/ScriptCollected events.
-    this.dispatchEventToListeners(SDK.DebuggerModel.Events.GlobalObjectCleared);
+    this.dispatchEventToListeners(SDK.DebuggerModel.Events.GlobalObjectCleared, this);
   }
 
   _reset() {
@@ -415,7 +415,7 @@
         if (!this._beforePausedCallback.call(null, this._debuggerPausedDetails))
           return false;
       }
-      this.dispatchEventToListeners(SDK.DebuggerModel.Events.DebuggerPaused, this._debuggerPausedDetails);
+      this.dispatchEventToListeners(SDK.DebuggerModel.Events.DebuggerPaused, this);
     }
     if (debuggerPausedDetails)
       this.setSelectedCallFrame(debuggerPausedDetails.callFrames[0]);
@@ -447,7 +447,7 @@
 
   _resumedScript() {
     this._setDebuggerPausedDetails(null);
-    this.dispatchEventToListeners(SDK.DebuggerModel.Events.DebuggerResumed);
+    this.dispatchEventToListeners(SDK.DebuggerModel.Events.DebuggerResumed, this);
   }
 
   /**
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/ResourceTreeModel.js b/third_party/WebKit/Source/devtools/front_end/sdk/ResourceTreeModel.js
index a6fea2b..eae9251 100644
--- a/third_party/WebKit/Source/devtools/front_end/sdk/ResourceTreeModel.js
+++ b/third_party/WebKit/Source/devtools/front_end/sdk/ResourceTreeModel.js
@@ -106,7 +106,7 @@
     this._cachedResourcesProcessed = true;
     this.target().runtimeModel.setExecutionContextComparator(this._executionContextComparator.bind(this));
     this.target().runtimeModel.fireExecutionContextOrderChanged();
-    this.dispatchEventToListeners(SDK.ResourceTreeModel.Events.CachedResourcesLoaded);
+    this.dispatchEventToListeners(SDK.ResourceTreeModel.Events.CachedResourcesLoaded, this);
   }
 
   /**
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/Script.js b/third_party/WebKit/Source/devtools/front_end/sdk/Script.js
index 177b47e..882aba8d 100644
--- a/third_party/WebKit/Source/devtools/front_end/sdk/Script.js
+++ b/third_party/WebKit/Source/devtools/front_end/sdk/Script.js
@@ -289,7 +289,7 @@
     if (this.sourceMapURL)
       return;
     this.sourceMapURL = sourceMapURL;
-    this.dispatchEventToListeners(SDK.Script.Events.SourceMapURLAdded, this.sourceMapURL);
+    this.dispatchEventToListeners(SDK.Script.Events.SourceMapURLAdded, this);
   }
 
   /**
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/ServiceWorkerCacheModel.js b/third_party/WebKit/Source/devtools/front_end/sdk/ServiceWorkerCacheModel.js
index 42a8245c..f6fe747 100644
--- a/third_party/WebKit/Source/devtools/front_end/sdk/ServiceWorkerCacheModel.js
+++ b/third_party/WebKit/Source/devtools/front_end/sdk/ServiceWorkerCacheModel.js
@@ -234,14 +234,14 @@
    * @param {!SDK.ServiceWorkerCacheModel.Cache} cache
    */
   _cacheAdded(cache) {
-    this.dispatchEventToListeners(SDK.ServiceWorkerCacheModel.Events.CacheAdded, cache);
+    this.dispatchEventToListeners(SDK.ServiceWorkerCacheModel.Events.CacheAdded, {model: this, cache: cache});
   }
 
   /**
    * @param {!SDK.ServiceWorkerCacheModel.Cache} cache
    */
   _cacheRemoved(cache) {
-    this.dispatchEventToListeners(SDK.ServiceWorkerCacheModel.Events.CacheRemoved, cache);
+    this.dispatchEventToListeners(SDK.ServiceWorkerCacheModel.Events.CacheRemoved, {model: this, cache: cache});
   }
 
   /**
diff --git a/third_party/WebKit/Source/devtools/front_end/snippets/ScriptSnippetModel.js b/third_party/WebKit/Source/devtools/front_end/snippets/ScriptSnippetModel.js
index 0dc5259ff..0dc66a2 100644
--- a/third_party/WebKit/Source/devtools/front_end/snippets/ScriptSnippetModel.js
+++ b/third_party/WebKit/Source/devtools/front_end/snippets/ScriptSnippetModel.js
@@ -119,7 +119,7 @@
    * @param {!Common.Event} event
    */
   _workingCopyChanged(event) {
-    var uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.target);
+    var uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data);
     this._scriptSnippetEdited(uiSourceCode);
   }
 
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js b/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js
index 770c950..d6ecba64 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js
+++ b/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js
@@ -284,6 +284,9 @@
         .then(populateSourceMapMembers.bind(this));
   }
 
+  /**
+   * @param {!Common.Event} event
+   */
   _workingCopyChanged(event) {
     if (this._supportsEnabledBreakpointsWhileEditing() || this._scriptFileForTarget.size)
       return;
@@ -294,6 +297,9 @@
       this._restoreBreakpointsAfterEditing();
   }
 
+  /**
+   * @param {!Common.Event} event
+   */
   _workingCopyCommitted(event) {
     this._scriptsPanel.updateLastModificationTime();
     if (this._supportsEnabledBreakpointsWhileEditing())
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/ScriptFormatterEditorAction.js b/third_party/WebKit/Source/devtools/front_end/sources/ScriptFormatterEditorAction.js
index 402627f..6955edd 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/ScriptFormatterEditorAction.js
+++ b/third_party/WebKit/Source/devtools/front_end/sources/ScriptFormatterEditorAction.js
@@ -293,7 +293,7 @@
    * @param {!Common.Event} event
    */
   _debuggerReset(event) {
-    var debuggerModel = /** @type {!SDK.DebuggerModel} */ (event.target);
+    var debuggerModel = /** @type {!SDK.DebuggerModel} */ (event.data);
     this._cleanForTarget(debuggerModel.target());
   }
 
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/SourcesPanel.js b/third_party/WebKit/Source/devtools/front_end/sources/SourcesPanel.js
index fc305dd..b373530 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/SourcesPanel.js
+++ b/third_party/WebKit/Source/devtools/front_end/sources/SourcesPanel.js
@@ -111,9 +111,11 @@
     SDK.targetManager.addModelListener(
         SDK.DebuggerModel, SDK.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this);
     SDK.targetManager.addModelListener(
-        SDK.DebuggerModel, SDK.DebuggerModel.Events.DebuggerResumed, this._debuggerResumed, this);
+        SDK.DebuggerModel, SDK.DebuggerModel.Events.DebuggerResumed,
+        (event) => this._debuggerResumed(/** @type {!SDK.DebuggerModel} */ (event.data)));
     SDK.targetManager.addModelListener(
-        SDK.DebuggerModel, SDK.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this);
+        SDK.DebuggerModel, SDK.DebuggerModel.Events.GlobalObjectCleared,
+        (event) => this._debuggerResumed(/** @type {!SDK.DebuggerModel} */ (event.data)));
     SDK.targetManager.addModelListener(
         SDK.SubTargetsManager, SDK.SubTargetsManager.Events.PendingTargetAdded, this._pendingTargetAdded, this);
     new Sources.WorkspaceMappingTip(this, this._workspace);
@@ -288,7 +290,8 @@
    * @param {!Common.Event} event
    */
   _debuggerPaused(event) {
-    var details = /** @type {!SDK.DebuggerPausedDetails} */ (event.data);
+    var debuggerModel = /** @type {!SDK.DebuggerModel} */ (event.data);
+    var details = debuggerModel.debuggerPausedDetails();
     if (!this._paused)
       this._setAsCurrentPanel();
 
@@ -312,10 +315,9 @@
   }
 
   /**
-   * @param {!Common.Event} event
+   * @param {!SDK.DebuggerModel} debuggerModel
    */
-  _debuggerResumed(event) {
-    var debuggerModel = /** @type {!SDK.DebuggerModel} */ (event.target);
+  _debuggerResumed(debuggerModel) {
     var target = debuggerModel.target();
     if (UI.context.flavor(SDK.Target) !== target)
       return;
@@ -329,21 +331,14 @@
    * @param {!Common.Event} event
    */
   _debuggerWasEnabled(event) {
-    var target = /** @type {!SDK.Target} */ (event.target.target());
-    if (UI.context.flavor(SDK.Target) !== target)
+    var debuggerModel = /** @type {!SDK.DebuggerModel} */ (event.data);
+    if (UI.context.flavor(SDK.Target) !== debuggerModel.target())
       return;
 
     this._updateDebuggerButtonsAndStatus();
   }
 
   /**
-   * @param {!Common.Event} event
-   */
-  _debuggerReset(event) {
-    this._debuggerResumed(event);
-  }
-
-  /**
    * @return {?UI.Widget}
    */
   get visibleView() {
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/SourcesView.js b/third_party/WebKit/Source/devtools/front_end/sources/SourcesView.js
index 949e9ea..6bfd606d3 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/SourcesView.js
+++ b/third_party/WebKit/Source/devtools/front_end/sources/SourcesView.js
@@ -483,7 +483,7 @@
    * @param {!Common.Event} event
    */
   _uiSourceCodeTitleChanged(event) {
-    this._recreateSourceFrameIfNeeded(/** @type {!Workspace.UISourceCode} */ (event.target));
+    this._recreateSourceFrameIfNeeded(/** @type {!Workspace.UISourceCode} */ (event.data));
   }
 
   /**
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/TabbedEditorContainer.js b/third_party/WebKit/Source/devtools/front_end/sources/TabbedEditorContainer.js
index 4a669a4..8e163c3 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/TabbedEditorContainer.js
+++ b/third_party/WebKit/Source/devtools/front_end/sources/TabbedEditorContainer.js
@@ -548,19 +548,28 @@
     }
   }
 
+  /**
+   * @param {!Common.Event} event
+   */
   _uiSourceCodeTitleChanged(event) {
-    var uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.target);
+    var uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data);
     this._updateFileTitle(uiSourceCode);
     this._updateHistory();
   }
 
+  /**
+   * @param {!Common.Event} event
+   */
   _uiSourceCodeWorkingCopyChanged(event) {
-    var uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.target);
+    var uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data);
     this._updateFileTitle(uiSourceCode);
   }
 
+  /**
+   * @param {!Common.Event} event
+   */
   _uiSourceCodeWorkingCopyCommitted(event) {
-    var uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.target);
+    var uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data.uiSourceCode);
     this._updateFileTitle(uiSourceCode);
   }
 
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/ThreadsSidebarPane.js b/third_party/WebKit/Source/devtools/front_end/sources/ThreadsSidebarPane.js
index 835d064..8247d9e 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/ThreadsSidebarPane.js
+++ b/third_party/WebKit/Source/devtools/front_end/sources/ThreadsSidebarPane.js
@@ -199,7 +199,7 @@
    * @param {!Common.Event} event
    */
   _onDebuggerStateChanged(event) {
-    var debuggerModel = /** @type {!SDK.DebuggerModel} */ (event.target);
+    var debuggerModel = /** @type {!SDK.DebuggerModel} */ (event.data);
     var pendingTarget = this._targetToPending.get(debuggerModel.target());
     this._updateDebuggerState(pendingTarget);
   }
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/WatchExpressionsSidebarPane.js b/third_party/WebKit/Source/devtools/front_end/sources/WatchExpressionsSidebarPane.js
index fd34603..0ef1d30 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/WatchExpressionsSidebarPane.js
+++ b/third_party/WebKit/Source/devtools/front_end/sources/WatchExpressionsSidebarPane.js
@@ -116,7 +116,7 @@
     this._emptyElement.classList.add('hidden');
     var watchExpression = new Sources.WatchExpression(expression, this._expandController, this._linkifier);
     watchExpression.addEventListener(
-        Sources.WatchExpression.Events.ExpressionUpdated, this._watchExpressionUpdated.bind(this));
+        Sources.WatchExpression.Events.ExpressionUpdated, this._watchExpressionUpdated, this);
     this._bodyElement.appendChild(watchExpression.element());
     this._watchExpressions.push(watchExpression);
     return watchExpression;
@@ -126,7 +126,7 @@
    * @param {!Common.Event} event
    */
   _watchExpressionUpdated(event) {
-    var watchExpression = /** @type {!Sources.WatchExpression} */ (event.target);
+    var watchExpression = /** @type {!Sources.WatchExpression} */ (event.data);
     if (!watchExpression.expression()) {
       this._watchExpressions.remove(watchExpression);
       this._bodyElement.removeChild(watchExpression.element());
@@ -304,7 +304,7 @@
       this._expandController.stopWatchSectionsWithId(this._expression);
     this._expression = newExpression;
     this.update();
-    this.dispatchEventToListeners(Sources.WatchExpression.Events.ExpressionUpdated);
+    this.dispatchEventToListeners(Sources.WatchExpression.Events.ExpressionUpdated, this);
   }
 
   /**
diff --git a/third_party/WebKit/Source/devtools/front_end/ui_lazy/DataGrid.js b/third_party/WebKit/Source/devtools/front_end/ui_lazy/DataGrid.js
index 9534f7f..0527edc 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui_lazy/DataGrid.js
+++ b/third_party/WebKit/Source/devtools/front_end/ui_lazy/DataGrid.js
@@ -1737,7 +1737,7 @@
       this._element.classList.add('selected');
 
     if (!supressSelectedEvent)
-      this.dataGrid.dispatchEventToListeners(UI.DataGrid.Events.SelectedNode);
+      this.dataGrid.dispatchEventToListeners(UI.DataGrid.Events.SelectedNode, this);
   }
 
   revealAndSelect() {
diff --git a/third_party/WebKit/Source/devtools/front_end/workspace/UISourceCode.js b/third_party/WebKit/Source/devtools/front_end/workspace/UISourceCode.js
index 13276a2..5a4b6735 100644
--- a/third_party/WebKit/Source/devtools/front_end/workspace/UISourceCode.js
+++ b/third_party/WebKit/Source/devtools/front_end/workspace/UISourceCode.js
@@ -180,7 +180,7 @@
       this._url = url;
     if (contentType)
       this._contentType = contentType;
-    this.dispatchEventToListeners(Workspace.UISourceCode.Events.TitleChanged, oldURL);
+    this.dispatchEventToListeners(Workspace.UISourceCode.Events.TitleChanged, this);
   }
 
   /**
@@ -347,7 +347,8 @@
     }
 
     this._innerResetWorkingCopy();
-    this.dispatchEventToListeners(Workspace.UISourceCode.Events.WorkingCopyCommitted, {content: content});
+    this.dispatchEventToListeners(
+        Workspace.UISourceCode.Events.WorkingCopyCommitted, {uiSourceCode: this, content: content});
     this._project.workspace().dispatchEventToListeners(
         Workspace.Workspace.Events.WorkingCopyCommitted, {uiSourceCode: this, content: content});
     if (committedByUser) {
@@ -456,7 +457,7 @@
 
   _workingCopyChanged() {
     this._removeAllMessages();
-    this.dispatchEventToListeners(Workspace.UISourceCode.Events.WorkingCopyChanged);
+    this.dispatchEventToListeners(Workspace.UISourceCode.Events.WorkingCopyChanged, this);
     this._project.workspace().dispatchEventToListeners(
         Workspace.Workspace.Events.WorkingCopyChanged, {uiSourceCode: this});
   }
diff --git a/third_party/WebKit/Source/devtools/scripts/build/generate_supported_css.py b/third_party/WebKit/Source/devtools/scripts/build/generate_supported_css.py
index a5993f77..91fcb910 100755
--- a/third_party/WebKit/Source/devtools/scripts/build/generate_supported_css.py
+++ b/third_party/WebKit/Source/devtools/scripts/build/generate_supported_css.py
@@ -49,6 +49,8 @@
             entry = {"name": name}
             if "inherited" in attributes:
                 entry["inherited"] = True
+            if "svg" in attributes:
+                entry["svg"] = True
             propertyNames.add(name)
             longhands = line.partition("longhands=")[2].partition(",")[0]
             if longhands:
diff --git a/third_party/WebKit/Source/platform/heap/BlinkGCAPIReference.md b/third_party/WebKit/Source/platform/heap/BlinkGCAPIReference.md
index e9815c3d..8a7abc5 100644
--- a/third_party/WebKit/Source/platform/heap/BlinkGCAPIReference.md
+++ b/third_party/WebKit/Source/platform/heap/BlinkGCAPIReference.md
@@ -178,17 +178,10 @@
 
 A pre-finalizer must have the following function signature: `void preFinalizer()`. You can change the function name.
 
-A pre-finalizer must be registered in the constructor by using the following statement:
-"`ThreadState::current()->registerPreFinalizer(this);`".
-
 ```c++
 class YourClass : public GarbageCollectedFinalized<YourClass> {
     USING_PRE_FINALIZER(YourClass, dispose);
 public:
-    YourClass()
-    {
-        ThreadState::current()->registerPreFinalizer(this);
-    }
     void dispose()
     {
         m_other->dispose(); // OK; you can touch other on-heap objects in a pre-finalizer.
diff --git a/third_party/WebKit/Source/platform/heap/HeapTest.cpp b/third_party/WebKit/Source/platform/heap/HeapTest.cpp
index 12ed78e4..aae128a 100644
--- a/third_party/WebKit/Source/platform/heap/HeapTest.cpp
+++ b/third_party/WebKit/Source/platform/heap/HeapTest.cpp
@@ -1160,7 +1160,6 @@
   ~ObservableWithPreFinalizer() { m_wasDestructed = true; }
   DEFINE_INLINE_TRACE() {}
   void dispose() {
-    ThreadState::current()->unregisterPreFinalizer(this);
     EXPECT_FALSE(m_wasDestructed);
     s_disposeWasCalled = true;
   }
@@ -1168,7 +1167,6 @@
 
  protected:
   ObservableWithPreFinalizer() : m_wasDestructed(false) {
-    ThreadState::current()->registerPreFinalizer(this);
   }
 
   bool m_wasDestructed;
@@ -1197,7 +1195,6 @@
 
  protected:
   PreFinalizerBase() : m_wasDestructed(false) {
-    ThreadState::current()->registerPreFinalizer(this);
   }
   bool m_wasDestructed;
 };
@@ -1218,7 +1215,6 @@
 
  protected:
   PreFinalizerMixin() : m_wasDestructed(false) {
-    ThreadState::current()->registerPreFinalizer(this);
   }
   bool m_wasDestructed;
 };
@@ -1241,7 +1237,6 @@
 
  protected:
   PreFinalizerSubClass() : m_wasDestructed(false) {
-    ThreadState::current()->registerPreFinalizer(this);
   }
   bool m_wasDestructed;
 };
@@ -1561,7 +1556,6 @@
  public:
   PreFinalizationAllocator(Persistent<IntWrapper>* wrapper)
       : m_wrapper(wrapper) {
-    ThreadState::current()->registerPreFinalizer(this);
   }
 
   void dispose() {
@@ -3881,25 +3875,11 @@
 
 TEST(HeapTest, PreFinalizer) {
   Observable::s_willFinalizeWasCalled = false;
-  {
-    Observable* foo = Observable::create(Bar::create());
-    ThreadState::current()->registerPreFinalizer(foo);
-  }
+  { Observable::create(Bar::create()); }
   preciselyCollectGarbage();
   EXPECT_TRUE(Observable::s_willFinalizeWasCalled);
 }
 
-TEST(HeapTest, PreFinalizerIsNotCalledIfUnregistered) {
-  Observable::s_willFinalizeWasCalled = false;
-  {
-    Observable* foo = Observable::create(Bar::create());
-    ThreadState::current()->registerPreFinalizer(foo);
-    ThreadState::current()->unregisterPreFinalizer(foo);
-  }
-  preciselyCollectGarbage();
-  EXPECT_FALSE(Observable::s_willFinalizeWasCalled);
-}
-
 TEST(HeapTest, PreFinalizerUnregistersItself) {
   ObservableWithPreFinalizer::s_disposeWasCalled = false;
   ObservableWithPreFinalizer::create();
diff --git a/third_party/WebKit/Source/platform/heap/ThreadState.h b/third_party/WebKit/Source/platform/heap/ThreadState.h
index 6ab0903e..a34732f 100644
--- a/third_party/WebKit/Source/platform/heap/ThreadState.h
+++ b/third_party/WebKit/Source/platform/heap/ThreadState.h
@@ -91,11 +91,6 @@
 //
 // class Foo : GarbageCollected<Foo> {
 //     USING_PRE_FINALIZER(Foo, dispose);
-// public:
-//     Foo()
-//     {
-//         ThreadState::current()->registerPreFinalizer(this);
-//     }
 // private:
 //     void dispose()
 //     {
@@ -103,15 +98,18 @@
 //     }
 //     Member<Bar> m_bar;
 // };
-#define USING_PRE_FINALIZER(Class, preFinalizer)    \
- public:                                            \
-  static bool invokePreFinalizer(void* object) {    \
-    Class* self = reinterpret_cast<Class*>(object); \
-    if (ThreadHeap::isHeapObjectAlive(self))        \
-      return false;                                 \
-    self->Class::preFinalizer();                    \
-    return true;                                    \
-  }                                                 \
+#define USING_PRE_FINALIZER(Class, preFinalizer)                           \
+ public:                                                                   \
+  static bool invokePreFinalizer(void* object) {                           \
+    Class* self = reinterpret_cast<Class*>(object);                        \
+    if (ThreadHeap::isHeapObjectAlive(self))                               \
+      return false;                                                        \
+    self->Class::preFinalizer();                                           \
+    return true;                                                           \
+  }                                                                        \
+                                                                           \
+ private:                                                                  \
+  ThreadState::PrefinalizerRegistration<Class> m_prefinalizerDummy = this; \
   using UsingPreFinalizerMacroNeedsTrailingSemiColon = char
 
 class PLATFORM_EXPORT ThreadState {
@@ -415,32 +413,9 @@
 
   size_t objectPayloadSizeForTesting();
 
-  // Register the pre-finalizer for the |self| object. This method is normally
-  // called in the constructor of the |self| object. The class T must have
-  // USING_PRE_FINALIZER().
+  // TODO: no longer needed, remove all uses.
   template <typename T>
   void registerPreFinalizer(T* self) {
-    static_assert(sizeof(&T::invokePreFinalizer) > 0,
-                  "USING_PRE_FINALIZER(T) must be defined.");
-    ASSERT(checkThread());
-    ASSERT(!sweepForbidden());
-    ASSERT(!m_orderedPreFinalizers.contains(
-        PreFinalizer(self, T::invokePreFinalizer)));
-    m_orderedPreFinalizers.add(PreFinalizer(self, T::invokePreFinalizer));
-  }
-
-  // Unregister the pre-finalizer for the |self| object.
-  template <typename T>
-  void unregisterPreFinalizer(T* self) {
-    static_assert(sizeof(&T::invokePreFinalizer) > 0,
-                  "USING_PRE_FINALIZER(T) must be defined.");
-    ASSERT(checkThread());
-    // Ignore pre-finalizers called during pre-finalizers or destructors.
-    if (sweepForbidden())
-      return;
-    ASSERT(m_orderedPreFinalizers.contains(
-        PreFinalizer(self, T::invokePreFinalizer)));
-    m_orderedPreFinalizers.remove(PreFinalizer(self, &T::invokePreFinalizer));
   }
 
   void shouldFlushHeapDoesNotContainCache() {
@@ -565,7 +540,29 @@
   void collectGarbageForTerminatingThread();
   void collectAllGarbage();
 
+  // Register the pre-finalizer for the |self| object. The class T must have
+  // USING_PRE_FINALIZER().
+  template <typename T>
+  class PrefinalizerRegistration final {
+   public:
+    PrefinalizerRegistration(T* self) {
+      static_assert(sizeof(&T::invokePreFinalizer) > 0,
+                    "USING_PRE_FINALIZER(T) must be defined.");
+      ThreadState* state = ThreadState::current();
+#if ENABLE(ASSERT)
+      DCHECK(state->checkThread());
+#endif
+      DCHECK(!state->sweepForbidden());
+      DCHECK(!state->m_orderedPreFinalizers.contains(
+          PreFinalizer(self, T::invokePreFinalizer)));
+      state->m_orderedPreFinalizers.add(
+          PreFinalizer(self, T::invokePreFinalizer));
+    }
+  };
+
  private:
+  template <typename T>
+  friend class PrefinalizerRegistration;
   enum SnapshotType { HeapSnapshot, FreelistSnapshot };
 
   explicit ThreadState(BlinkGC::ThreadHeapMode);
diff --git a/third_party/WebKit/Source/platform/weborigin/SecurityOrigin.cpp b/third_party/WebKit/Source/platform/weborigin/SecurityOrigin.cpp
index 50a2bbe..c84b6ea 100644
--- a/third_party/WebKit/Source/platform/weborigin/SecurityOrigin.cpp
+++ b/third_party/WebKit/Source/platform/weborigin/SecurityOrigin.cpp
@@ -571,6 +571,12 @@
   return isSameSchemeHostPort(other) && sameSuborigins;
 }
 
+bool SecurityOrigin::areSameSchemeHostPort(const KURL& a, const KURL& b) {
+  RefPtr<SecurityOrigin> originA = SecurityOrigin::create(a);
+  RefPtr<SecurityOrigin> originB = SecurityOrigin::create(b);
+  return originB->isSameSchemeHostPort(originA.get());
+}
+
 const KURL& SecurityOrigin::urlWithUniqueSecurityOrigin() {
   ASSERT(isMainThread());
   DEFINE_STATIC_LOCAL(const KURL, uniqueSecurityOriginURL,
diff --git a/third_party/WebKit/Source/platform/weborigin/SecurityOrigin.h b/third_party/WebKit/Source/platform/weborigin/SecurityOrigin.h
index 77ca5864..a82e280 100644
--- a/third_party/WebKit/Source/platform/weborigin/SecurityOrigin.h
+++ b/third_party/WebKit/Source/platform/weborigin/SecurityOrigin.h
@@ -250,6 +250,8 @@
   bool isSameSchemeHostPort(const SecurityOrigin*) const;
   bool isSameSchemeHostPortAndSuborigin(const SecurityOrigin*) const;
 
+  static bool areSameSchemeHostPort(const KURL& a, const KURL& b);
+
   static const KURL& urlWithUniqueSecurityOrigin();
 
   // Transfer origin privileges from another security origin.
diff --git a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
index de74b3f..bdcc802 100644
--- a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
+++ b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
@@ -9697,14 +9697,14 @@
   FrameTestHelpers::loadFrame(webLocalChild, m_baseURL + "foo.html");
   LocalFrame* localChild = toWebLocalFrameImpl(webLocalChild)->frame();
   EXPECT_FALSE(page->suspended());
-  EXPECT_FALSE(localChild->document()->fetcher()->defersLoading());
+  EXPECT_FALSE(localChild->document()->fetcher()->context().defersLoading());
   {
     ScopedPageSuspender suspender;
     EXPECT_TRUE(page->suspended());
-    EXPECT_TRUE(localChild->document()->fetcher()->defersLoading());
+    EXPECT_TRUE(localChild->document()->fetcher()->context().defersLoading());
   }
   EXPECT_FALSE(page->suspended());
-  EXPECT_FALSE(localChild->document()->fetcher()->defersLoading());
+  EXPECT_FALSE(localChild->document()->fetcher()->context().defersLoading());
 
   view->close();
 }
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 1bd84dc3..ccde36a 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -44740,6 +44740,7 @@
 
 <histogram name="Platform.CrOSEvent" enum="CrosEventEnum">
   <owner>dkrahn@chromium.org</owner>
+  <owner>jwerner@chromium.org</owner>
   <summary>
     Generic event of interest from Chrome OS.  Intended mainly to help assess
     the frequency of rare error conditions.
@@ -80396,6 +80397,13 @@
   <int value="10" label="SpringPowerSupply.ChargerIdle"/>
   <int value="11" label="TPM.NonZeroDictionaryAttackCounter"/>
   <int value="12" label="TPM.EarlyResetDuringCommand"/>
+  <int value="13" label="VeyronEmmcUpgrade.Success"/>
+  <int value="14" label="VeyronEmmcUpgrade.WaitForKernelRollup"/>
+  <int value="15" label="VeyronEmmcUpgrade.WaitForFirmwareRollup"/>
+  <int value="16" label="VeyronEmmcUpgrade.BadEmmcProperties"/>
+  <int value="17" label="VeyronEmmcUpgrade.FailedDiskAccess"/>
+  <int value="18" label="VeyronEmmcUpgrade.FailedWPEnable"/>
+  <int value="19" label="VeyronEmmcUpgrade.SignatureDetected"/>
 </enum>
 
 <enum name="CrosFirstRunTutorialCompletionType" type="int">