diff --git a/DEPS b/DEPS
index 27b08bcb..a8300368 100644
--- a/DEPS
+++ b/DEPS
@@ -44,7 +44,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'v8_revision': '49810c744f6f030780e07554b1fd830466a27353',
+  'v8_revision': 'd80c92bb602288bc35cecbf63b43ee7f9a8edd08',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling swarming_client
   # and whatever else without interference from each other.
diff --git a/ash/shell_unittest.cc b/ash/shell_unittest.cc
index 881b972..0aa8d19 100644
--- a/ash/shell_unittest.cc
+++ b/ash/shell_unittest.cc
@@ -170,10 +170,7 @@
     EXPECT_NE(views::MenuController::EXIT_NONE, menu_controller->exit_type());
     lock_widget->Close();
     delegate->UnlockScreen();
-
-    // In case the menu wasn't closed, cancel the menu to exit the nested menu
-    // run loop so that the test will not time out.
-    menu_controller->CancelAll();
+    EXPECT_EQ(nullptr, views::MenuController::GetActiveInstance());
   }
 };
 
@@ -348,20 +345,15 @@
                               ->GetRootWindowController()
                               ->wallpaper_widget_controller()
                               ->widget();
-  std::unique_ptr<views::MenuRunner> menu_runner(
-      new views::MenuRunner(menu_model.get(), views::MenuRunner::CONTEXT_MENU));
-
-  // When MenuRunner runs a nested loop the LockScreenAndVerifyMenuClosed
-  // command will fire, check the menu state and ensure the nested menu loop
-  // is exited so that the test will terminate.
-  base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::Bind(&ShellTest::LockScreenAndVerifyMenuClosed,
-                            base::Unretained(this)));
+  std::unique_ptr<views::MenuRunner> menu_runner(new views::MenuRunner(
+      menu_model.get(),
+      views::MenuRunner::CONTEXT_MENU | views::MenuRunner::ASYNC));
 
   EXPECT_EQ(views::MenuRunner::NORMAL_EXIT,
             menu_runner->RunMenuAt(widget, NULL, gfx::Rect(),
                                    views::MENU_ANCHOR_TOPLEFT,
                                    ui::MENU_SOURCE_MOUSE));
+  LockScreenAndVerifyMenuClosed();
 }
 
 TEST_F(ShellTest, ManagedWindowModeBasics) {
diff --git a/base/memory/ref_counted.h b/base/memory/ref_counted.h
index ff46e6d6..37012de 100644
--- a/base/memory/ref_counted.h
+++ b/base/memory/ref_counted.h
@@ -354,14 +354,10 @@
     return *this;
   }
 
-  void swap(T** pp) {
-    T* p = ptr_;
-    ptr_ = *pp;
-    *pp = p;
-  }
-
   void swap(scoped_refptr<T>& r) {
-    swap(&r.ptr_);
+    T* tmp = ptr_;
+    ptr_ = r.ptr_;
+    r.ptr_ = tmp;
   }
 
   explicit operator bool() const { return ptr_ != nullptr; }
diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc
index 478f481e..63e7dd4 100644
--- a/cc/output/gl_renderer.cc
+++ b/cc/output/gl_renderer.cc
@@ -1536,7 +1536,7 @@
 
   // Only apply anti-aliasing to edges not clipped by culling or scissoring.
   // If an edge is degenerate we do not want to replace it with a "proper" edge
-  // as that will cause the quad to possibly expand is strange ways.
+  // as that will cause the quad to possibly expand in strange ways.
   if (!top_edge.degenerate() && is_top(clip_region, quad) &&
       tile_rect.y() == quad->rect.y()) {
     top_edge = device_layer_edges.top();
diff --git a/chrome/android/java/res/values/dimens.xml b/chrome/android/java/res/values/dimens.xml
index 5d2d4357..fbdb7b11 100644
--- a/chrome/android/java/res/values/dimens.xml
+++ b/chrome/android/java/res/values/dimens.xml
@@ -395,6 +395,7 @@
          is doubled. -->
     <dimen name="pref_autofill_dropdown_bottom_margin">16dp</dimen>
     <dimen name="pref_autofill_touch_target_padding">15dp</dimen>
+    <dimen name="pref_child_account_reduced_padding">4dp</dimen>
 
     <!-- Dialog dimensions.
          https://www.google.com/design/spec/components/dialogs.html#dialogs-simple-dialogs -->
diff --git a/chrome/android/java/res/xml/account_management_preferences.xml b/chrome/android/java/res/xml/account_management_preferences.xml
index 4b4b09cb..4215dcba 100644
--- a/chrome/android/java/res/xml/account_management_preferences.xml
+++ b/chrome/android/java/res/xml/account_management_preferences.xml
@@ -23,9 +23,11 @@
         android:key="parental_settings"
         android:title="@string/account_management_parental_settings"
         android:order="1001" />
-    <Preference
+
+    <org.chromium.chrome.browser.preferences.ChromeBasePreference
         android:key="parent_accounts"
         android:order="1002" />
+
     <Preference
         android:key="child_content"
         android:title="@string/account_management_child_content_title"
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagementDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagementDelegate.java
index 1809d59..a85e33b0 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagementDelegate.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagementDelegate.java
@@ -56,13 +56,6 @@
     void onCloseContextualSearch(StateChangeReason reason);
 
     /**
-     * This is called on navigation of the contextual search pane This is called on navigation
-     * of the contextual search panel.
-     * @param isFailure If the request resulted in an error page.
-     */
-    void onContextualSearchRequestNavigation(boolean isFailure);
-
-    /**
      * @return An OverlayContentDelegate to watch events on the panel's content.
      */
     OverlayContentDelegate getOverlayContentDelegate();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java
index 5287bd6f..7a75b3a 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java
@@ -1070,8 +1070,7 @@
      * a load of a user-visible search result.
      * @param isFailure Whether the navigation failed.
      */
-    @Override
-    public void onContextualSearchRequestNavigation(boolean isFailure) {
+    private void onContextualSearchRequestNavigation(boolean isFailure) {
         if (mSearchRequest == null) return;
 
         if (mSearchRequest.isUsingLowPriority()) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/ChromeBasePreference.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/ChromeBasePreference.java
index 6d43d53..e40afe6 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/ChromeBasePreference.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/ChromeBasePreference.java
@@ -10,6 +10,8 @@
 import android.view.View;
 import android.widget.TextView;
 
+import org.chromium.chrome.R;
+
 /**
  * A preference that supports some Chrome-specific customizations:
  *
@@ -20,8 +22,8 @@
  * 2. This preference can have a multiline title.
  */
 public class ChromeBasePreference extends Preference {
-
     private ManagedPreferenceDelegate mManagedPrefDelegate;
+    private boolean mUseReducedPadding;
 
     /**
      * Constructor for use in Java.
@@ -45,11 +47,16 @@
         if (mManagedPrefDelegate != null) mManagedPrefDelegate.initPreference(this);
     }
 
+    public void setUseReducedPadding(boolean useReducedPadding) {
+        this.mUseReducedPadding = useReducedPadding;
+    }
+
     @Override
     protected void onBindView(View view) {
         super.onBindView(view);
         ((TextView) view.findViewById(android.R.id.title)).setSingleLine(false);
         if (mManagedPrefDelegate != null) mManagedPrefDelegate.onBindViewToPreference(this, view);
+        if (mUseReducedPadding) reducePadding(view);
     }
 
     @Override
@@ -57,4 +64,23 @@
         if (mManagedPrefDelegate != null && mManagedPrefDelegate.onClickPreference(this)) return;
         super.onClick();
     }
+
+    private void reducePadding(View view) {
+        View innerLayout = (View) view.findViewById(android.R.id.title).getParent();
+
+        if (getIcon() != null) {
+            // When there is an icon, it is bigger than the text (account name here) and it already
+            // has the appropriate padding. So we let the icon dictate the top and bottom padding
+            // for the preference and just let the text get centered in that space.
+            // TODO(dgn): would look ugly in account names that are 2+ lines, but unlikely to occur.
+            innerLayout.setPadding(
+                    innerLayout.getPaddingLeft(), 0, innerLayout.getPaddingRight(), 0);
+            return;
+        }
+
+        int topPaddingPx = getContext().getResources().getDimensionPixelOffset(
+                R.dimen.pref_child_account_reduced_padding);
+        innerLayout.setPadding(innerLayout.getPaddingLeft(), topPaddingPx,
+                innerLayout.getPaddingRight(), innerLayout.getPaddingBottom());
+    }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountManagementFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountManagementFragment.java
index 1549bb7..6bcee905 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountManagementFragment.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountManagementFragment.java
@@ -22,6 +22,7 @@
 import android.graphics.PorterDuffXfermode;
 import android.graphics.Rect;
 import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.UserManager;
@@ -32,6 +33,7 @@
 import android.text.TextUtils;
 import android.util.Pair;
 
+import org.chromium.base.ApiCompatibilityUtils;
 import org.chromium.base.ContextUtils;
 import org.chromium.base.metrics.RecordUserAction;
 import org.chromium.chrome.R;
@@ -374,6 +376,7 @@
             }
             parentAccounts.setSummary(parentText);
             parentAccounts.setSelectable(false);
+            ((ChromeBasePreference) parentAccounts).setUseReducedPadding(true);
 
             final int childContentSummary;
             int defaultBehavior = prefService.getDefaultSupervisedUserFilteringBehavior();
@@ -385,7 +388,16 @@
                 childContentSummary = R.string.account_management_child_content_all;
             }
             childContent.setSummary(childContentSummary);
-            childContent.setSelectable(false);
+            // TODO(dgn): made selectable to show the dividers. Find a way to avoid this. A side
+            // effect is that it shows a tap ripple on an item that is not interactive.
+            // childContent.setSelectable(false);
+
+            Drawable newIcon = ApiCompatibilityUtils.getDrawable(
+                    getResources(), R.drawable.ic_drive_site_white_24dp);
+            newIcon.mutate().setColorFilter(
+                    ApiCompatibilityUtils.getColor(getResources(), R.color.google_grey_600),
+                    PorterDuff.Mode.SRC_IN);
+            childContent.setIcon(newIcon);
         } else {
             PreferenceScreen prefScreen = getPreferenceScreen();
             prefScreen.removePreference(findPreference(PREF_PARENTAL_SETTINGS));
@@ -413,7 +425,7 @@
             pref.setTitle(account.name);
 
             boolean isChildAccount = ChildAccountService.isChildAccount();
-
+            pref.setUseReducedPadding(isChildAccount);
             pref.setIcon(new BitmapDrawable(getResources(),
                     isChildAccount ? getBadgedUserPicture(account.name, getResources()) :
                         getUserPicture(account.name, getResources())));
diff --git a/chrome/browser/chromeos/policy/dm_token_storage.cc b/chrome/browser/chromeos/policy/dm_token_storage.cc
index 99a4acb..a3f86c40 100644
--- a/chrome/browser/chromeos/policy/dm_token_storage.cc
+++ b/chrome/browser/chromeos/policy/dm_token_storage.cc
@@ -5,7 +5,7 @@
 #include "chrome/browser/chromeos/policy/dm_token_storage.h"
 
 #include "base/bind.h"
-#include "base/threading/sequenced_worker_pool.h"
+#include "base/task_scheduler/post_task.h"
 #include "chrome/browser/chromeos/settings/token_encryptor.h"
 #include "chrome/common/pref_names.h"
 #include "chromeos/cryptohome/system_salt_getter.h"
@@ -17,14 +17,12 @@
 
 std::string EncryptToken(const std::string& system_salt,
                          const std::string& dm_token) {
-  DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
   chromeos::CryptohomeTokenEncryptor encryptor(system_salt);
   return encryptor.EncryptWithSystemSalt(dm_token);
 }
 
 std::string DecryptToken(const std::string& system_salt,
                          const std::string encrypted_dm_token) {
-  DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
   chromeos::CryptohomeTokenEncryptor encryptor(system_salt);
   return encryptor.DecryptWithSystemSalt(encrypted_dm_token);
 }
@@ -129,8 +127,10 @@
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   DCHECK(!system_salt_.empty());
   DCHECK(!dm_token_.empty());
-  base::PostTaskAndReplyWithResult(
-      content::BrowserThread::GetBlockingPool(), FROM_HERE,
+  base::PostTaskWithTraitsAndReplyWithResult(
+      FROM_HERE,
+      base::TaskTraits().MayBlock().WithPriority(
+          base::TaskPriority::BACKGROUND),
       base::Bind(&EncryptToken, system_salt_, dm_token_),
       base::Bind(&DMTokenStorage::OnTokenEncrypted,
                  weak_ptr_factory_.GetWeakPtr()));
@@ -152,8 +152,10 @@
   std::string encrypted_dm_token =
       local_state_->GetString(prefs::kDeviceDMToken);
   if (!encrypted_dm_token.empty()) {
-    base::PostTaskAndReplyWithResult(
-        content::BrowserThread::GetBlockingPool(), FROM_HERE,
+    base::PostTaskWithTraitsAndReplyWithResult(
+        FROM_HERE,
+        base::TaskTraits().MayBlock().WithPriority(
+            base::TaskPriority::BACKGROUND),
         base::Bind(&DecryptToken, system_salt_, encrypted_dm_token),
         base::Bind(&DMTokenStorage::FlushRetrieveTokenCallback,
                    weak_ptr_factory_.GetWeakPtr()));
diff --git a/chrome/browser/metrics/chrome_metrics_service_client.cc b/chrome/browser/metrics/chrome_metrics_service_client.cc
index 291cb4b5..3131bc3bd 100644
--- a/chrome/browser/metrics/chrome_metrics_service_client.cc
+++ b/chrome/browser/metrics/chrome_metrics_service_client.cc
@@ -227,12 +227,13 @@
       base::GlobalHistogramAllocator::ConstructFilePaths(
           user_data_dir, kCrashpadHistogramAllocatorName, nullptr,
           &active_path);
-      // Register data that will be populated for the current run.
+      // Register data that will be populated for the current run. "Active"
+      // files need an empty "prefs_key" because they update the file itself.
       file_metrics_provider->RegisterSource(
           active_path,
           metrics::FileMetricsProvider::SOURCE_HISTOGRAMS_ACTIVE_FILE,
           metrics::FileMetricsProvider::ASSOCIATE_CURRENT_RUN,
-          kCrashpadHistogramAllocatorName);
+          base::StringPiece());
     }
   }
 
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.cc b/chrome/browser/password_manager/chrome_password_manager_client.cc
index 30420b6..7e02fbb 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client.cc
+++ b/chrome/browser/password_manager/chrome_password_manager_client.cc
@@ -10,6 +10,7 @@
 #include "base/bind.h"
 #include "base/bind_helpers.h"
 #include "base/command_line.h"
+#include "base/memory/ref_counted.h"
 #include "base/memory/singleton.h"
 #include "base/metrics/field_trial.h"
 #include "base/metrics/histogram_macros.h"
@@ -50,6 +51,7 @@
 #include "components/sessions/content/content_record_password_state.h"
 #include "components/signin/core/browser/signin_manager.h"
 #include "components/version_info/version_info.h"
+#include "content/public/browser/browser_thread.h"
 #include "content/public/browser/child_process_security_policy.h"
 #include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/navigation_handle.h"
@@ -139,6 +141,22 @@
           profile->GetPrefs()));
 }
 
+bool IsHSTSActiveForHostAndRequestContext(
+    const GURL& origin,
+    const scoped_refptr<net::URLRequestContextGetter>& request_context) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+  if (!origin.is_valid())
+    return false;
+
+  net::TransportSecurityState* security_state =
+      request_context->GetURLRequestContext()->transport_security_state();
+
+  if (!security_state)
+    return false;
+
+  return security_state->ShouldUpgradeToSSL(origin.host());
+}
+
 }  // namespace
 
 // static
@@ -240,20 +258,14 @@
          IsPasswordManagementEnabledForCurrentPage();
 }
 
-bool ChromePasswordManagerClient::IsHSTSActiveForHost(
-    const GURL& origin) const {
-  if (!origin.is_valid())
-    return false;
-
-  net::TransportSecurityState* security_state =
-      profile_->GetRequestContext()
-          ->GetURLRequestContext()
-          ->transport_security_state();
-
-  if (!security_state)
-    return false;
-
-  return security_state->ShouldUpgradeToSSL(origin.host());
+void ChromePasswordManagerClient::PostHSTSQueryForHost(
+    const GURL& origin,
+    const HSTSCallback& callback) const {
+  content::BrowserThread::PostTaskAndReplyWithResult(
+      content::BrowserThread::IO, FROM_HERE,
+      base::Bind(&IsHSTSActiveForHostAndRequestContext, origin,
+                 make_scoped_refptr(profile_->GetRequestContext())),
+      callback);
 }
 
 bool ChromePasswordManagerClient::OnCredentialManagerUsed() {
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.h b/chrome/browser/password_manager/chrome_password_manager_client.h
index a695608..ab47052c 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client.h
+++ b/chrome/browser/password_manager/chrome_password_manager_client.h
@@ -48,7 +48,8 @@
   // PasswordManagerClient implementation.
   bool IsSavingAndFillingEnabledForCurrentPage() const override;
   bool IsFillingEnabledForCurrentPage() const override;
-  bool IsHSTSActiveForHost(const GURL& origin) const override;
+  void PostHSTSQueryForHost(const GURL& origin,
+                            const HSTSCallback& callback) const override;
   bool OnCredentialManagerUsed() override;
   bool PromptUserToSaveOrUpdatePassword(
       std::unique_ptr<password_manager::PasswordFormManager> form_to_save,
diff --git a/chrome/browser/password_manager/credential_manager_browsertest.cc b/chrome/browser/password_manager/credential_manager_browsertest.cc
index 4520685..75f5147 100644
--- a/chrome/browser/password_manager/credential_manager_browsertest.cc
+++ b/chrome/browser/password_manager/credential_manager_browsertest.cc
@@ -16,8 +16,6 @@
 #include "components/password_manager/core/browser/test_password_store.h"
 #include "content/public/test/browser_test.h"
 #include "content/public/test/browser_test_utils.h"
-#include "net/cert/cert_verify_result.h"
-#include "net/cert/mock_cert_verifier.h"
 #include "net/dns/mock_host_resolver.h"
 
 namespace {
@@ -44,20 +42,7 @@
     observer.Wait();
   }
 
-  void SetUpInProcessBrowserTestFixture() override {
-    ProfileIOData::SetCertVerifierForTesting(&mock_cert_verifier_);
-  }
-
-  void TearDownInProcessBrowserTestFixture() override {
-    ProfileIOData::SetCertVerifierForTesting(nullptr);
-  }
-
-  net::MockCertVerifier& mock_cert_verifier() {
-    return mock_cert_verifier_;
-  }
-
  private:
-  net::MockCertVerifier mock_cert_verifier_;
   DISALLOW_COPY_AND_ASSIGN(CredentialManagerBrowserTest);
 };
 
@@ -118,14 +103,6 @@
 
 IN_PROC_BROWSER_TEST_F(CredentialManagerBrowserTest,
                        StoreSavesPSLMatchedCredential) {
-  // Setup mock certificate for all origins.
-  auto cert = https_test_server().GetCertificate();
-  net::CertVerifyResult verify_result;
-  verify_result.cert_status = 0;
-  verify_result.is_issued_by_known_root = true;
-  verify_result.verified_cert = cert;
-  mock_cert_verifier().AddResultForCert(cert.get(), verify_result, net::OK);
-
   // Redirect all requests to localhost.
   host_resolver()->AddRule("*", "127.0.0.1");
 
@@ -186,6 +163,64 @@
 }
 
 IN_PROC_BROWSER_TEST_F(CredentialManagerBrowserTest,
+                       ObsoleteHttpCredentialMovedOnMigrationToHstsSite) {
+  // Add an http credential to the password store.
+  GURL https_origin = https_test_server().base_url();
+  ASSERT_TRUE(https_origin.SchemeIs(url::kHttpsScheme));
+  GURL::Replacements rep;
+  rep.SetSchemeStr(url::kHttpScheme);
+  GURL http_origin = https_origin.ReplaceComponents(rep);
+  autofill::PasswordForm http_form;
+  http_form.signon_realm = http_origin.spec();
+  http_form.origin = http_origin;
+  http_form.username_value = base::ASCIIToUTF16("user");
+  http_form.password_value = base::ASCIIToUTF16("12345");
+  scoped_refptr<password_manager::TestPasswordStore> password_store =
+      static_cast<password_manager::TestPasswordStore*>(
+          PasswordStoreFactory::GetForProfile(
+              browser()->profile(), ServiceAccessType::IMPLICIT_ACCESS)
+              .get());
+  password_store->AddLogin(http_form);
+  WaitForPasswordStore();
+
+  // Treat the host of the HTTPS test server as HSTS.
+  AddHSTSHost(https_test_server().host_port_pair().host());
+
+  // Navigate to HTTPS page and trigger the migration.
+  ui_test_utils::NavigateToURL(
+      browser(), https_test_server().GetURL("/password/done.html"));
+
+  // Call the API to trigger |get| and |store| and redirect.
+  ASSERT_TRUE(content::ExecuteScript(
+      RenderViewHost(), "navigator.credentials.get({password: true})"));
+
+  // Issue the query for HTTPS credentials.
+  WaitForPasswordStore();
+
+  // Realize there are no HTTPS credentials and issue the query for HTTP
+  // credentials instead.
+  WaitForPasswordStore();
+
+  // Sync with IO thread before continuing. This is necessary, because the
+  // credential migration triggers a query for the HSTS state which gets
+  // executed on the IO thread. The actual task is empty, because only the reply
+  // is relevant. By the time the reply is executed it is guaranteed that the
+  // migration is completed.
+  const auto empty_lambda = []() {};
+  base::RunLoop run_loop;
+  content::BrowserThread::PostTaskAndReply(content::BrowserThread::IO,
+                                           FROM_HERE, base::Bind(empty_lambda),
+                                           run_loop.QuitClosure());
+  run_loop.Run();
+
+  // Only HTTPS passwords should be present.
+  EXPECT_TRUE(
+      password_store->stored_passwords().at(http_origin.spec()).empty());
+  EXPECT_FALSE(
+      password_store->stored_passwords().at(https_origin.spec()).empty());
+}
+
+IN_PROC_BROWSER_TEST_F(CredentialManagerBrowserTest,
                        AutoSigninOldCredentialAndNavigation) {
   // Save credentials with 'skip_zero_click' false.
   scoped_refptr<password_manager::TestPasswordStore> password_store =
diff --git a/chrome/browser/password_manager/password_manager_browsertest.cc b/chrome/browser/password_manager/password_manager_browsertest.cc
index 3598b35..cb0e771 100644
--- a/chrome/browser/password_manager/password_manager_browsertest.cc
+++ b/chrome/browser/password_manager/password_manager_browsertest.cc
@@ -1381,11 +1381,6 @@
 IN_PROC_BROWSER_TEST_F(
     PasswordManagerBrowserTestBase,
     NoPromptForLoginFailedAndServerPushSeperateLoginForm_HttpsToHttp) {
-  base::CommandLine::ForCurrentProcess()->AppendSwitch(
-      ::switches::kAllowRunningInsecureContent);
-  base::CommandLine::ForCurrentProcess()->AppendSwitch(
-      ::switches::kIgnoreCertificateErrors);
-
   // This test case cannot inject the scripts via content::ExecuteScript() in
   // files served through HTTPS. Therefore the scripts are made part of the HTML
   // site and executed on load.
@@ -1410,11 +1405,6 @@
 IN_PROC_BROWSER_TEST_F(
     PasswordManagerBrowserTestBase,
     NoPromptForSeperateLoginFormWhenSwitchingFromHttpsToHttp) {
-  base::CommandLine::ForCurrentProcess()->AppendSwitch(
-      ::switches::kAllowRunningInsecureContent);
-  base::CommandLine::ForCurrentProcess()->AppendSwitch(
-      ::switches::kIgnoreCertificateErrors);
-
   std::string path = "/password/password_form.html";
   GURL https_url(https_test_server().GetURL(path));
   ASSERT_TRUE(https_url.SchemeIs(url::kHttpsScheme));
@@ -1511,6 +1501,63 @@
   CheckElementValue("password_field", "12345");
 }
 
+// Tests that obsolete HTTP credentials are moved when a site migrated to HTTPS
+// and has HSTS enabled.
+IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
+                       ObsoleteHttpCredentialMovedOnMigrationToHstsSite) {
+  // Add an http credential to the password store.
+  GURL https_origin = https_test_server().base_url();
+  ASSERT_TRUE(https_origin.SchemeIs(url::kHttpsScheme));
+  GURL::Replacements rep;
+  rep.SetSchemeStr(url::kHttpScheme);
+  GURL http_origin = https_origin.ReplaceComponents(rep);
+  autofill::PasswordForm http_form;
+  http_form.signon_realm = http_origin.spec();
+  http_form.origin = http_origin;
+  http_form.username_value = base::ASCIIToUTF16("user");
+  http_form.password_value = base::ASCIIToUTF16("12345");
+  scoped_refptr<password_manager::TestPasswordStore> password_store =
+      static_cast<password_manager::TestPasswordStore*>(
+          PasswordStoreFactory::GetForProfile(
+              browser()->profile(), ServiceAccessType::IMPLICIT_ACCESS)
+              .get());
+  password_store->AddLogin(http_form);
+
+  // Treat the host of the HTTPS test server as HSTS.
+  AddHSTSHost(https_test_server().host_port_pair().host());
+
+  // Navigate to HTTPS page and trigger the migration.
+  NavigationObserver form_observer(WebContents());
+  ui_test_utils::NavigateToURL(
+      browser(), https_test_server().GetURL("/password/password_form.html"));
+  form_observer.Wait();
+
+  // Issue the query for HTTPS credentials.
+  WaitForPasswordStore();
+
+  // Realize there are no HTTPS credentials and issue the query for HTTP
+  // credentials instead.
+  WaitForPasswordStore();
+
+  // Sync with IO thread before continuing. This is necessary, because the
+  // credential migration triggers a query for the HSTS state which gets
+  // executed on the IO thread. The actual task is empty, because only the reply
+  // is relevant. By the time the reply is executed it is guaranteed that the
+  // migration is completed.
+  const auto empty_lambda = []() {};
+  base::RunLoop run_loop;
+  content::BrowserThread::PostTaskAndReply(content::BrowserThread::IO,
+                                           FROM_HERE, base::Bind(empty_lambda),
+                                           run_loop.QuitClosure());
+  run_loop.Run();
+
+  // Only HTTPS passwords should be present.
+  EXPECT_TRUE(
+      password_store->stored_passwords().at(http_origin.spec()).empty());
+  EXPECT_FALSE(
+      password_store->stored_passwords().at(https_origin.spec()).empty());
+}
+
 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
                        PromptWhenPasswordFormWithoutUsernameFieldSubmitted) {
   scoped_refptr<password_manager::TestPasswordStore> password_store =
diff --git a/chrome/browser/password_manager/password_manager_test_base.cc b/chrome/browser/password_manager/password_manager_test_base.cc
index c398a21..9ac7ec53 100644
--- a/chrome/browser/password_manager/password_manager_test_base.cc
+++ b/chrome/browser/password_manager/password_manager_test_base.cc
@@ -7,10 +7,12 @@
 #include <string>
 
 #include "base/macros.h"
+#include "base/memory/ref_counted.h"
 #include "base/run_loop.h"
 #include "base/strings/stringprintf.h"
 #include "chrome/browser/password_manager/password_store_factory.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/profiles/profile_io_data.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
@@ -23,7 +25,11 @@
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/test/browser_test_utils.h"
 #include "content/public/test/test_utils.h"
+#include "net/cert/cert_verify_result.h"
+#include "net/http/transport_security_state.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
+#include "net/url_request/url_request_context.h"
+#include "net/url_request/url_request_context_getter.h"
 
 namespace {
 
@@ -47,6 +53,23 @@
   DISALLOW_COPY_AND_ASSIGN(PasswordStoreResultsObserver);
 };
 
+void AddHSTSHostImpl(
+    const scoped_refptr<net::URLRequestContextGetter>& request_context,
+    const std::string& host) {
+  ASSERT_TRUE(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+  net::TransportSecurityState* transport_security_state =
+      request_context->GetURLRequestContext()->transport_security_state();
+  if (!transport_security_state) {
+    ADD_FAILURE();
+    return;
+  }
+
+  base::Time expiry = base::Time::Now() + base::TimeDelta::FromDays(1000);
+  bool include_subdomains = false;
+  transport_security_state->AddHSTS(host, expiry, include_subdomains);
+  EXPECT_TRUE(transport_security_state->ShouldUpgradeToSSL(host));
+}
+
 }  // namespace
 
 NavigationObserver::NavigationObserver(content::WebContents* web_contents)
@@ -137,12 +160,28 @@
       FILE_PATH_LITERAL("chrome/test/data");
   https_test_server().ServeFilesFromSourceDirectory(base::FilePath(kDocRoot));
   ASSERT_TRUE(https_test_server().Start());
+
+  // Whitelist all certs for the HTTPS server.
+  auto cert = https_test_server().GetCertificate();
+  net::CertVerifyResult verify_result;
+  verify_result.cert_status = 0;
+  verify_result.is_issued_by_known_root = true;
+  verify_result.verified_cert = cert;
+  mock_cert_verifier().AddResultForCert(cert.get(), verify_result, net::OK);
 }
 
 void PasswordManagerBrowserTestBase::TearDownOnMainThread() {
   ASSERT_TRUE(embedded_test_server()->ShutdownAndWaitUntilComplete());
 }
 
+void PasswordManagerBrowserTestBase::SetUpInProcessBrowserTestFixture() {
+  ProfileIOData::SetCertVerifierForTesting(&mock_cert_verifier_);
+}
+
+void PasswordManagerBrowserTestBase::TearDownInProcessBrowserTestFixture() {
+  ProfileIOData::SetCertVerifierForTesting(nullptr);
+}
+
 content::WebContents* PasswordManagerBrowserTestBase::WebContents() {
   return browser()->tab_strip_model()->GetActiveWebContents();
 }
@@ -291,3 +330,16 @@
   EXPECT_TRUE(return_value) << "element_id = " << element_id
                             << ", expected_value = " << expected_value;
 }
+
+void PasswordManagerBrowserTestBase::AddHSTSHost(const std::string& host) {
+  base::RunLoop run_loop;
+
+  content::BrowserThread::PostTaskAndReply(
+      content::BrowserThread::IO, FROM_HERE,
+      base::Bind(&AddHSTSHostImpl,
+                 make_scoped_refptr(browser()->profile()->GetRequestContext()),
+                 host),
+      run_loop.QuitClosure());
+
+  run_loop.Run();
+}
diff --git a/chrome/browser/password_manager/password_manager_test_base.h b/chrome/browser/password_manager/password_manager_test_base.h
index bb095d7..61e773b 100644
--- a/chrome/browser/password_manager/password_manager_test_base.h
+++ b/chrome/browser/password_manager/password_manager_test_base.h
@@ -12,6 +12,7 @@
 #include "components/password_manager/core/browser/password_store_consumer.h"
 #include "content/public/browser/web_contents_observer.h"
 #include "content/public/test/test_utils.h"
+#include "net/cert/mock_cert_verifier.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
 
 namespace autofill {
@@ -96,6 +97,8 @@
   // InProcessBrowserTest:
   void SetUpOnMainThread() override;
   void TearDownOnMainThread() override;
+  void SetUpInProcessBrowserTestFixture() override;
+  void TearDownInProcessBrowserTestFixture() override;
 
  protected:
   // Wrapper around ui_test_utils::NavigateToURL that waits until
@@ -136,13 +139,18 @@
                          const std::string& element_id,
                          const std::string& expected_value);
 
+  // Synchronoulsy adds the given host to the list of valid HSTS hosts.
+  void AddHSTSHost(const std::string& host);
+
   // Accessors
   content::WebContents* WebContents();
   content::RenderViewHost* RenderViewHost();
   net::EmbeddedTestServer& https_test_server() { return https_test_server_; }
+  net::MockCertVerifier& mock_cert_verifier() { return mock_cert_verifier_; }
 
  private:
   net::EmbeddedTestServer https_test_server_;
+  net::MockCertVerifier mock_cert_verifier_;
   DISALLOW_COPY_AND_ASSIGN(PasswordManagerBrowserTestBase);
 };
 
diff --git a/chrome/browser/signin/OWNERS b/chrome/browser/signin/OWNERS
index 265baae0..931d7ff 100644
--- a/chrome/browser/signin/OWNERS
+++ b/chrome/browser/signin/OWNERS
@@ -13,3 +13,6 @@
 per-file screenlock_bridge*=tbarzic@chromium.org
 per-file screenlock_bridge*=tengs@chromium.org
 per-file screenlock_bridge*=xiyuan@chromium.org
+
+# TEAM: chrome-signin@chromium.org
+# COMPONENT: Services>SignIn
diff --git a/chrome/browser/ui/views/menu_controller_interactive_uitest.cc b/chrome/browser/ui/views/menu_controller_interactive_uitest.cc
index 33874d17..498d2177 100644
--- a/chrome/browser/ui/views/menu_controller_interactive_uitest.cc
+++ b/chrome/browser/ui/views/menu_controller_interactive_uitest.cc
@@ -93,32 +93,3 @@
 #endif
 
 VIEW_TEST(MenuControllerMnemonicTestNoMatch, MAYBE_NoMatch);
-
-class MenuRunnerCancelTest : public MenuTestBase {
- public:
-  MenuRunnerCancelTest() {}
-
-  // MenuTestBase overrides:
-  void BuildMenu(views::MenuItemView* menu) override {
-    menu->AppendMenuItemWithLabel(1, base::ASCIIToUTF16("One&/"));
-    menu->AppendMenuItemWithLabel(2, base::ASCIIToUTF16("Two"));
-  }
-
-  void DoTestWithMenuOpen() override {
-    ASSERT_EQ(true, menu_runner()->IsRunning());
-    menu_runner()->Cancel();
-    // On calling Cancel, the nested message loop spun by the menu, should be
-    // marked for termination. However, since we are still in the last
-    // iteration of the nested message loop, MenuRunner::IsRunning(), should
-    // return true.
-    ASSERT_EQ(true, menu_runner()->IsRunning());
-    Done();
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(MenuRunnerCancelTest);
-};
-
-// Test that MenuRunner::IsRunning() returns true, immediately after calling
-// MenuRunner::Cancel() for a syncronous menu.
-VIEW_TEST(MenuRunnerCancelTest, IsRunningAfterCancel);
diff --git a/chrome/browser/ui/views/menu_model_adapter_test.cc b/chrome/browser/ui/views/menu_model_adapter_test.cc
index 080f62d..732e2fd1 100644
--- a/chrome/browser/ui/views/menu_model_adapter_test.cc
+++ b/chrome/browser/ui/views/menu_model_adapter_test.cc
@@ -174,8 +174,8 @@
                                     this, true);
 
     menu_ = menu_model_adapter_.CreateMenu();
-    menu_runner_.reset(
-        new views::MenuRunner(menu_, views::MenuRunner::HAS_MNEMONICS));
+    menu_runner_.reset(new views::MenuRunner(
+        menu_, views::MenuRunner::HAS_MNEMONICS | views::MenuRunner::ASYNC));
 
     ViewEventTestBase::SetUp();
   }
diff --git a/chrome/browser/ui/views/menu_test_base.cc b/chrome/browser/ui/views/menu_test_base.cc
index 4889b56d..f7b5aa91 100644
--- a/chrome/browser/ui/views/menu_test_base.cc
+++ b/chrome/browser/ui/views/menu_test_base.cc
@@ -38,7 +38,7 @@
 }
 
 int MenuTestBase::GetMenuRunnerFlags() {
-  return views::MenuRunner::HAS_MNEMONICS;
+  return views::MenuRunner::HAS_MNEMONICS | views::MenuRunner::ASYNC;
 }
 
 void MenuTestBase::SetUp() {
diff --git a/chrome/browser/ui/views/menu_view_drag_and_drop_test.cc b/chrome/browser/ui/views/menu_view_drag_and_drop_test.cc
index ec67c29..84e09ce 100644
--- a/chrome/browser/ui/views/menu_view_drag_and_drop_test.cc
+++ b/chrome/browser/ui/views/menu_view_drag_and_drop_test.cc
@@ -462,9 +462,8 @@
 };
 
 int MenuViewDragAndDropForDropStayOpen::GetMenuRunnerFlags() {
-  return views::MenuRunner::HAS_MNEMONICS |
-         views::MenuRunner::NESTED_DRAG |
-         views::MenuRunner::FOR_DROP;
+  return views::MenuRunner::HAS_MNEMONICS | views::MenuRunner::NESTED_DRAG |
+         views::MenuRunner::FOR_DROP | views::MenuRunner::ASYNC;
 }
 
 void MenuViewDragAndDropForDropStayOpen::DoTestWithMenuOpen() {
@@ -496,7 +495,8 @@
 };
 
 int MenuViewDragAndDropForDropCancel::GetMenuRunnerFlags() {
-  return views::MenuRunner::HAS_MNEMONICS | views::MenuRunner::FOR_DROP;
+  return views::MenuRunner::HAS_MNEMONICS | views::MenuRunner::FOR_DROP |
+         views::MenuRunner::ASYNC;
 }
 
 void MenuViewDragAndDropForDropCancel::DoTestWithMenuOpen() {
diff --git a/chrome/test/data/safe_browsing/dmg/make_hfs.sh b/chrome/test/data/safe_browsing/dmg/make_hfs.sh
index bc478c4..129dfd0d 100755
--- a/chrome/test/data/safe_browsing/dmg/make_hfs.sh
+++ b/chrome/test/data/safe_browsing/dmg/make_hfs.sh
@@ -74,6 +74,6 @@
 popd  # Original PWD
 
 # Unmount the volume, copy the raw device to a file, and then destroy it.
-diskutil unmount ${RAMDISK_VOLUME}
+diskutil unmount force ${RAMDISK_VOLUME}
 dd if=${RAMDISK_VOLUME} of="${OUT_FILE}" &> /dev/null
 diskutil eject ${RAMDISK_VOLUME}
diff --git a/components/autofill/core/browser/autofill_manager.cc b/components/autofill/core/browser/autofill_manager.cc
index 056793f..3b646f2a 100644
--- a/components/autofill/core/browser/autofill_manager.cc
+++ b/components/autofill/core/browser/autofill_manager.cc
@@ -60,6 +60,7 @@
 #include "components/autofill/core/common/form_data_predictions.h"
 #include "components/autofill/core/common/form_field_data.h"
 #include "components/autofill/core/common/password_form_fill_data.h"
+#include "components/autofill/core/common/signatures_util.h"
 #include "components/pref_registry/pref_registry_syncable.h"
 #include "components/prefs/pref_service.h"
 #include "components/rappor/public/rappor_utils.h"
@@ -1689,7 +1690,7 @@
   if (!FindCachedForm(form, &cached_submitted_form))
     return std::unique_ptr<FormStructure>();
 
-  submitted_form->UpdateFromCache(*cached_submitted_form);
+  submitted_form->UpdateFromCache(*cached_submitted_form, false);
   return submitted_form;
 }
 
@@ -1702,8 +1703,9 @@
   // protocol with the crowdsourcing server does not permit us to discard the
   // original versions of the forms.
   *form_structure = NULL;
+  const auto& form_signature = autofill::CalculateFormSignature(form);
   for (auto& cur_form : base::Reversed(form_structures_)) {
-    if (*cur_form == form) {
+    if (cur_form->form_signature() == form_signature || *cur_form == form) {
       *form_structure = cur_form.get();
 
       // The same form might be cached with multiple field counts: in some
@@ -1785,41 +1787,17 @@
   if (!needs_update)
     return true;
 
-  if (form_structures_.size() >= kMaxFormCacheSize)
+  // Note: We _must not_ remove the original version of the cached form from
+  // the list of |form_structures_|. Otherwise, we break parsing of the
+  // crowdsourcing server's response to our query.
+  if (!ParseForm(live_form, updated_form))
     return false;
 
-  // Add the new or updated form to our cache.
-  form_structures_.push_back(base::MakeUnique<FormStructure>(live_form));
-  *updated_form = form_structures_.rbegin()->get();
-  (*updated_form)->DetermineHeuristicTypes();
-
-  // If we have cached data, propagate it to the updated form.
-  if (cached_form) {
-    std::map<base::string16, const AutofillField*> cached_fields;
-    for (size_t i = 0; i < cached_form->field_count(); ++i) {
-      const AutofillField* field = cached_form->field(i);
-      cached_fields[field->unique_name()] = field;
-    }
-
-    for (size_t i = 0; i < (*updated_form)->field_count(); ++i) {
-      AutofillField* field = (*updated_form)->field(i);
-      auto cached_field = cached_fields.find(field->unique_name());
-      if (cached_field != cached_fields.end()) {
-        field->set_server_type(cached_field->second->server_type());
-        field->is_autofilled = cached_field->second->is_autofilled;
-        field->set_previously_autofilled(
-            cached_field->second->previously_autofilled());
-      }
-    }
-
-    // Note: We _must not_ remove the original version of the cached form from
-    // the list of |form_structures_|.  Otherwise, we break parsing of the
-    // crowdsourcing server's response to our query.
-  }
+  if (cached_form)
+    (*updated_form)->UpdateFromCache(*cached_form, true);
 
   // Annotate the updated form with its predicted types.
-  std::vector<FormStructure*> forms(1, *updated_form);
-  driver_->SendAutofillTypePredictionsToRenderer(forms);
+  driver_->SendAutofillTypePredictionsToRenderer({*updated_form});
 
   return true;
 }
@@ -1880,23 +1858,17 @@
   for (const FormData& form : forms) {
     const auto parse_form_start_time = base::TimeTicks::Now();
 
-    std::unique_ptr<FormStructure> form_structure =
-        base::MakeUnique<FormStructure>(form);
-    form_structure->ParseFieldTypesFromAutocompleteAttributes();
-    if (!form_structure->ShouldBeParsed())
+    FormStructure* form_structure = nullptr;
+    if (!ParseForm(form, &form_structure))
       continue;
+    DCHECK(form_structure);
 
-    form_structure->DetermineHeuristicTypes();
-
-    // Ownership is transferred to |form_structures_| which maintains it until
-    // the manager is Reset() or destroyed. It is safe to use references below
-    // as long as receivers don't take ownership.
-    form_structures_.push_back(std::move(form_structure));
-
-    if (form_structures_.back()->ShouldBeCrowdsourced())
-      queryable_forms.push_back(form_structures_.back().get());
+    // Set aside forms with method GET or author-specified types, so that they
+    // are not included in the query to the server.
+    if (form_structure->ShouldBeCrowdsourced())
+      queryable_forms.push_back(form_structure);
     else
-      non_queryable_forms.push_back(form_structures_.back().get());
+      non_queryable_forms.push_back(form_structure);
 
     AutofillMetrics::LogParseFormTiming(base::TimeTicks::Now() -
                                         parse_form_start_time);
@@ -1938,6 +1910,26 @@
   driver_->SendAutofillTypePredictionsToRenderer(non_queryable_forms);
 }
 
+bool AutofillManager::ParseForm(const FormData& form,
+                                FormStructure** parsed_form_structure) {
+  DCHECK(parsed_form_structure);
+  if (form_structures_.size() >= kMaxFormCacheSize)
+    return false;
+
+  auto form_structure = base::MakeUnique<FormStructure>(form);
+  form_structure->ParseFieldTypesFromAutocompleteAttributes();
+  if (!form_structure->ShouldBeParsed())
+    return false;
+
+  // Ownership is transferred to |form_structures_| which maintains it until
+  // the manager is Reset() or destroyed. It is safe to use references below
+  // as long as receivers don't take ownership.
+  form_structures_.push_back(std::move(form_structure));
+  *parsed_form_structure = form_structures_.back().get();
+  (*parsed_form_structure)->DetermineHeuristicTypes();
+  return true;
+}
+
 int AutofillManager::BackendIDToInt(const std::string& backend_id) const {
   if (!base::IsValidGUID(backend_id))
     return 0;
diff --git a/components/autofill/core/browser/autofill_manager.h b/components/autofill/core/browser/autofill_manager.h
index 290126ec..e00a31b 100644
--- a/components/autofill/core/browser/autofill_manager.h
+++ b/components/autofill/core/browser/autofill_manager.h
@@ -414,6 +414,9 @@
   // Parses the forms using heuristic matching and querying the Autofill server.
   void ParseForms(const std::vector<FormData>& forms);
 
+  // Parses the form and adds it to |form_structures_|.
+  bool ParseForm(const FormData& form, FormStructure** parsed_form_structure);
+
   // Imports the form data, submitted by the user, into |personal_data_|.
   void ImportFormData(const FormStructure& submitted_form);
 
diff --git a/components/autofill/core/browser/autofill_manager_unittest.cc b/components/autofill/core/browser/autofill_manager_unittest.cc
index 54643c6..d33e0fe 100644
--- a/components/autofill/core/browser/autofill_manager_unittest.cc
+++ b/components/autofill/core/browser/autofill_manager_unittest.cc
@@ -8,6 +8,7 @@
 
 #include <algorithm>
 #include <memory>
+#include <utility>
 #include <vector>
 
 #include "base/command_line.h"
@@ -57,6 +58,7 @@
 #include "components/ukm/ukm_entry.h"
 #include "components/ukm/ukm_source.h"
 #include "components/variations/variations_associated_data.h"
+#include "net/base/url_util.h"
 #include "net/url_request/url_request_test_util.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -5742,4 +5744,96 @@
   }
 }
 
+// Tests that a form with server only types is still autofillable if the form
+// gets updated in cache.
+TEST_F(AutofillManagerTest, DisplaySuggestionsForUpdatedServerTypedForm) {
+  // Create a form with unknown heuristic fields.
+  FormData form;
+  form.name = ASCIIToUTF16("MyForm");
+  form.origin = GURL("http://myform.com/form.html");
+  form.action = GURL("http://myform.com/submit.html");
+
+  FormFieldData field;
+  test::CreateTestFormField("Field 1", "field1", "", "text", &field);
+  form.fields.push_back(field);
+  test::CreateTestFormField("Field 2", "field2", "", "text", &field);
+  form.fields.push_back(field);
+  test::CreateTestFormField("Field 3", "field3", "", "text", &field);
+  form.fields.push_back(field);
+
+  auto form_structure = base::MakeUnique<TestFormStructure>(form);
+  form_structure->DetermineHeuristicTypes();
+  // Make sure the form can not be autofilled now.
+  ASSERT_EQ(0u, form_structure->autofill_count());
+  for (size_t idx = 0; idx < form_structure->field_count(); ++idx) {
+    ASSERT_EQ(UNKNOWN_TYPE, form_structure->field(idx)->heuristic_type());
+  }
+
+  // Prepare and set known server fields.
+  const std::vector<ServerFieldType> heuristic_types(form.fields.size(),
+                                                     UNKNOWN_TYPE);
+  const std::vector<ServerFieldType> server_types{NAME_FIRST, NAME_MIDDLE,
+                                                  NAME_LAST};
+  form_structure->SetFieldTypes(heuristic_types, server_types);
+  autofill_manager_->AddSeenForm(std::move(form_structure));
+
+  // Make sure the form can be autofilled.
+  for (const FormFieldData& field : form.fields) {
+    GetAutofillSuggestions(form, field);
+    ASSERT_TRUE(external_delegate_->on_suggestions_returned_seen());
+  }
+
+  // Modify one of the fields in the original form.
+  form.fields[0].css_classes += ASCIIToUTF16("a");
+
+  // Expect the form still can be autofilled.
+  for (const FormFieldData& field : form.fields) {
+    GetAutofillSuggestions(form, field);
+    EXPECT_TRUE(external_delegate_->on_suggestions_returned_seen());
+  }
+
+  // Modify form action URL. This can happen on in-page navitaion if the form
+  // doesn't have an actual action (attribute is empty).
+  form.action = net::AppendQueryParameter(form.action, "arg", "value");
+
+  // Expect the form still can be autofilled.
+  for (const FormFieldData& field : form.fields) {
+    GetAutofillSuggestions(form, field);
+    EXPECT_TRUE(external_delegate_->on_suggestions_returned_seen());
+  }
+}
+
+// Tests that a form with <select> field is accepted if <option> value (not
+// content) is quite long. Some websites use value to propagate long JSON to
+// JS-backed logic.
+TEST_F(AutofillManagerTest, FormWithLongOptionValuesIsAcceptable) {
+  FormData form;
+  form.name = ASCIIToUTF16("MyForm");
+  form.origin = GURL("http://myform.com/form.html");
+  form.action = GURL("http://myform.com/submit.html");
+
+  FormFieldData field;
+  test::CreateTestFormField("First name", "firstname", "", "text", &field);
+  form.fields.push_back(field);
+  test::CreateTestFormField("Last name", "lastname", "", "text", &field);
+  form.fields.push_back(field);
+
+  // Prepare <select> field with long <option> values.
+  const size_t kOptionValueLength = 10240;
+  const std::string long_string(kOptionValueLength, 'a');
+  const std::vector<const char*> values(3, long_string.c_str());
+  const std::vector<const char*> contents{"A", "B", "C"};
+  test::CreateTestSelectField("Country", "country", "", values, contents,
+                              values.size(), &field);
+  form.fields.push_back(field);
+
+  FormsSeen({form});
+
+  // Suggestions should be displayed.
+  for (const FormFieldData& field : form.fields) {
+    GetAutofillSuggestions(form, field);
+    EXPECT_TRUE(external_delegate_->on_suggestions_returned_seen());
+  }
+}
+
 }  // namespace autofill
diff --git a/components/autofill/core/browser/form_structure.cc b/components/autofill/core/browser/form_structure.cc
index addf89f..02e861f 100644
--- a/components/autofill/core/browser/form_structure.cc
+++ b/components/autofill/core/browser/form_structure.cc
@@ -624,17 +624,16 @@
          ShouldBeParsed();
 }
 
-void FormStructure::UpdateFromCache(const FormStructure& cached_form) {
+void FormStructure::UpdateFromCache(const FormStructure& cached_form,
+                                    const bool apply_is_autofilled) {
   // Map from field signatures to cached fields.
-  std::map<std::string, const AutofillField*> cached_fields;
+  std::map<base::string16, const AutofillField*> cached_fields;
   for (size_t i = 0; i < cached_form.field_count(); ++i) {
     auto* const field = cached_form.field(i);
-    cached_fields[field->FieldSignatureAsStr()] = field;
+    cached_fields[field->unique_name()] = field;
   }
-
   for (auto& field : *this) {
-    std::map<std::string, const AutofillField*>::const_iterator cached_field =
-        cached_fields.find(field->FieldSignatureAsStr());
+    const auto& cached_field = cached_fields.find(field->unique_name());
     if (cached_field != cached_fields.end()) {
       if (field->form_control_type != "select-one" &&
           field->value == cached_field->second->value) {
@@ -649,6 +648,9 @@
       field->set_server_type(cached_field->second->server_type());
       field->SetHtmlType(cached_field->second->html_type(),
                          cached_field->second->html_mode());
+      if (apply_is_autofilled) {
+        field->is_autofilled = cached_field->second->is_autofilled;
+      }
       field->set_previously_autofilled(
           cached_field->second->previously_autofilled());
       field->set_section(cached_field->second->section());
@@ -662,9 +664,6 @@
   // rearranged via JavaScript between page load and form submission, so we
   // copy over the |form_signature_field_names_| corresponding to the query
   // request.
-  DCHECK_EQ(cached_form.form_name_, form_name_);
-  DCHECK_EQ(cached_form.source_url_, source_url_);
-  DCHECK_EQ(cached_form.target_url_, target_url_);
   form_signature_ = cached_form.form_signature_;
 }
 
diff --git a/components/autofill/core/browser/form_structure.h b/components/autofill/core/browser/form_structure.h
index 09c4ee1..e984a5f 100644
--- a/components/autofill/core/browser/form_structure.h
+++ b/components/autofill/core/browser/form_structure.h
@@ -116,7 +116,8 @@
   bool ShouldBeCrowdsourced() const;
 
   // Sets the field types to be those set for |cached_form|.
-  void UpdateFromCache(const FormStructure& cached_form);
+  void UpdateFromCache(const FormStructure& cached_form,
+                       const bool apply_is_autofilled);
 
   // Logs quality metrics for |this|, which should be a user-submitted form.
   // This method should only be called after the possible field types have been
diff --git a/components/autofill/core/common/autofill_data_validation.cc b/components/autofill/core/common/autofill_data_validation.cc
index 07c2b9d..f1075dc 100644
--- a/components/autofill/core/common/autofill_data_validation.cc
+++ b/components/autofill/core/common/autofill_data_validation.cc
@@ -35,7 +35,6 @@
          IsValidString16(field.value) &&
          IsValidString(field.form_control_type) &&
          IsValidString(field.autocomplete_attribute) &&
-         IsValidString16Vector(field.option_values) &&
          IsValidString16Vector(field.option_contents);
 }
 
diff --git a/components/metrics/file_metrics_provider.cc b/components/metrics/file_metrics_provider.cc
index 24cfa9b..65a1bae7 100644
--- a/components/metrics/file_metrics_provider.cc
+++ b/components/metrics/file_metrics_provider.cc
@@ -141,8 +141,10 @@
   source->prefs_key = prefs_key.as_string();
 
   switch (source->type) {
-    case SOURCE_HISTOGRAMS_ATOMIC_FILE:
     case SOURCE_HISTOGRAMS_ACTIVE_FILE:
+      DCHECK(prefs_key.empty());
+    // fall through
+    case SOURCE_HISTOGRAMS_ATOMIC_FILE:
       source->path = path;
       break;
     case SOURCE_HISTOGRAMS_ATOMIC_DIR:
diff --git a/components/metrics/file_metrics_provider.h b/components/metrics/file_metrics_provider.h
index 080a8211d..001fe83 100644
--- a/components/metrics/file_metrics_provider.h
+++ b/components/metrics/file_metrics_provider.h
@@ -90,8 +90,9 @@
   // within that directory are used. Because some metadata may need to persist
   // across process restarts, preferences entries are used based on the
   // |prefs_key| name. Call RegisterPrefs() with the same name to create the
-  // necessary keys in advance. Set |prefs_key| empty if no persistence is
-  // required.
+  // necessary keys in advance. Set |prefs_key| empty (nullptr will work) if
+  // no persistence is required. ACTIVE files shouldn't have a pref key as
+  // they update internal state about what has been previously sent.
   void RegisterSource(const base::FilePath& path,
                       SourceType type,
                       SourceAssociation source_association,
diff --git a/components/metrics/file_metrics_provider_unittest.cc b/components/metrics/file_metrics_provider_unittest.cc
index 1197709..9781cea 100644
--- a/components/metrics/file_metrics_provider_unittest.cc
+++ b/components/metrics/file_metrics_provider_unittest.cc
@@ -372,10 +372,9 @@
       base::GlobalHistogramAllocator::ReleaseForTesting();
 
   // Register the file and allow the "checker" task to run.
-  provider()->RegisterSource(metrics_file(),
-                             FileMetricsProvider::SOURCE_HISTOGRAMS_ACTIVE_FILE,
-                             FileMetricsProvider::ASSOCIATE_CURRENT_RUN,
-                             kMetricsName);
+  provider()->RegisterSource(
+      metrics_file(), FileMetricsProvider::SOURCE_HISTOGRAMS_ACTIVE_FILE,
+      FileMetricsProvider::ASSOCIATE_CURRENT_RUN, nullptr);
 
   // Record embedded snapshots via snapshot-manager.
   OnDidCreateMetricsLog();
diff --git a/components/password_manager/core/browser/credential_manager_pending_request_task.cc b/components/password_manager/core/browser/credential_manager_pending_request_task.cc
index 63c79bb0..c82cabf 100644
--- a/components/password_manager/core/browser/credential_manager_pending_request_task.cc
+++ b/components/password_manager/core/browser/credential_manager_pending_request_task.cc
@@ -134,8 +134,7 @@
   if (results.empty()) {
     // Try to migrate the HTTP passwords and process them later.
     http_migrator_ = base::MakeUnique<HttpPasswordMigrator>(
-        origin_, HttpPasswordMigrator::MigrationMode::COPY,
-        delegate_->client()->GetPasswordStore(), this);
+        origin_, delegate_->client(), this);
     return;
   }
   ProcessForms(std::move(results));
diff --git a/components/password_manager/core/browser/form_fetcher_impl.cc b/components/password_manager/core/browser/form_fetcher_impl.cc
index 6bff00d..4ba32f4 100644
--- a/components/password_manager/core/browser/form_fetcher_impl.cc
+++ b/components/password_manager/core/browser/form_fetcher_impl.cc
@@ -110,9 +110,8 @@
 
   if (should_migrate_http_passwords_ && results.empty() &&
       form_digest_.origin.SchemeIs(url::kHttpsScheme)) {
-    http_migrator_ = base::MakeUnique<HttpPasswordMigrator>(
-        form_digest_.origin, HttpPasswordMigrator::MigrationMode::COPY,
-        client_->GetPasswordStore(), this);
+    http_migrator_ = base::MakeUnique<HttpPasswordMigrator>(form_digest_.origin,
+                                                            client_, this);
     return;
   }
 
diff --git a/components/password_manager/core/browser/http_password_migrator.cc b/components/password_manager/core/browser/http_password_migrator.cc
index 700327ca..1bfb65e6 100644
--- a/components/password_manager/core/browser/http_password_migrator.cc
+++ b/components/password_manager/core/browser/http_password_migrator.cc
@@ -4,6 +4,8 @@
 
 #include "components/password_manager/core/browser/http_password_migrator.h"
 
+#include "base/memory/weak_ptr.h"
+#include "components/password_manager/core/browser/password_manager_client.h"
 #include "components/password_manager/core/browser/password_manager_metrics_util.h"
 #include "components/password_manager/core/browser/password_store.h"
 #include "url/gurl.h"
@@ -11,12 +13,26 @@
 
 namespace password_manager {
 
+namespace {
+
+// Helper method that allows us to pass WeakPtrs to |PasswordStoreConsumer|
+// obtained via |GetWeakPtr|. This is not possible otherwise.
+void OnHSTSQueryResultHelper(
+    const base::WeakPtr<PasswordStoreConsumer>& migrator,
+    bool is_hsts) {
+  if (migrator) {
+    static_cast<HttpPasswordMigrator*>(migrator.get())
+        ->OnHSTSQueryResult(is_hsts);
+  }
+}
+
+}  // namespace
+
 HttpPasswordMigrator::HttpPasswordMigrator(const GURL& https_origin,
-                                           MigrationMode mode,
-                                           PasswordStore* password_store,
+                                           const PasswordManagerClient* client,
                                            Consumer* consumer)
-    : mode_(mode), consumer_(consumer), password_store_(password_store) {
-  DCHECK(password_store_);
+    : client_(client), consumer_(consumer) {
+  DCHECK(client_);
   DCHECK(https_origin.is_valid());
   DCHECK(https_origin.SchemeIs(url::kHttpsScheme)) << https_origin;
 
@@ -25,25 +41,45 @@
   GURL http_origin = https_origin.ReplaceComponents(rep);
   PasswordStore::FormDigest form(autofill::PasswordForm::SCHEME_HTML,
                                  http_origin.GetOrigin().spec(), http_origin);
-  password_store_->GetLogins(form, this);
+  client_->GetPasswordStore()->GetLogins(form, this);
+  client_->PostHSTSQueryForHost(
+      https_origin, base::Bind(&OnHSTSQueryResultHelper, GetWeakPtr()));
 }
 
 HttpPasswordMigrator::~HttpPasswordMigrator() = default;
 
 void HttpPasswordMigrator::OnGetPasswordStoreResults(
     std::vector<std::unique_ptr<autofill::PasswordForm>> results) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  results_ = std::move(results);
+  got_password_store_results_ = true;
+
+  if (got_hsts_query_result_)
+    ProcessPasswordStoreResults();
+}
+
+void HttpPasswordMigrator::OnHSTSQueryResult(bool is_hsts) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  mode_ = is_hsts ? MigrationMode::MOVE : MigrationMode::COPY;
+  got_hsts_query_result_ = true;
+
+  if (got_password_store_results_)
+    ProcessPasswordStoreResults();
+}
+
+void HttpPasswordMigrator::ProcessPasswordStoreResults() {
   // Android and PSL matches are ignored.
-  results.erase(
-      std::remove_if(results.begin(), results.end(),
+  results_.erase(
+      std::remove_if(results_.begin(), results_.end(),
                      [](const std::unique_ptr<autofill::PasswordForm>& form) {
                        return form->is_affiliation_based_match ||
                               form->is_public_suffix_match;
                      }),
-      results.end());
+      results_.end());
 
   // Add the new credentials to the password store. The HTTP forms are
   // removed iff |mode_| == MigrationMode::MOVE.
-  for (const auto& form : results) {
+  for (const auto& form : results_) {
     autofill::PasswordForm new_form = *form;
 
     GURL::Replacements rep;
@@ -57,17 +93,24 @@
     new_form.form_data = autofill::FormData();
     new_form.generation_upload_status = autofill::PasswordForm::NO_SIGNAL_SENT;
     new_form.skip_zero_click = false;
-    password_store_->AddLogin(new_form);
+    client_->GetPasswordStore()->AddLogin(new_form);
 
     if (mode_ == MigrationMode::MOVE)
-      password_store_->RemoveLogin(*form);
+      client_->GetPasswordStore()->RemoveLogin(*form);
     *form = std::move(new_form);
   }
 
-  metrics_util::LogCountHttpMigratedPasswords(results.size());
+  if (!results_.empty()) {
+    // Only log data if there was at least one migrated password.
+    metrics_util::LogCountHttpMigratedPasswords(results_.size());
+    metrics_util::LogHttpPasswordMigrationMode(
+        mode_ == MigrationMode::MOVE
+            ? metrics_util::HTTP_PASSWORD_MIGRATION_MODE_MOVE
+            : metrics_util::HTTP_PASSWORD_MIGRATION_MODE_COPY);
+  }
 
   if (consumer_)
-    consumer_->ProcessMigratedForms(std::move(results));
+    consumer_->ProcessMigratedForms(std::move(results_));
 }
 
 }  // namespace password_manager
diff --git a/components/password_manager/core/browser/http_password_migrator.h b/components/password_manager/core/browser/http_password_migrator.h
index 7d9d096..4f71156 100644
--- a/components/password_manager/core/browser/http_password_migrator.h
+++ b/components/password_manager/core/browser/http_password_migrator.h
@@ -9,6 +9,7 @@
 #include <vector>
 
 #include "base/macros.h"
+#include "base/threading/thread_checker.h"
 #include "components/password_manager/core/browser/password_store_consumer.h"
 
 namespace autofill {
@@ -19,17 +20,16 @@
 
 namespace password_manager {
 
-class PasswordStore;
+class PasswordManagerClient;
 
 // The class is responsible for migrating the passwords saved on HTTP to HTTPS
-// origin.
+// origin. It automatically determines whether HTTP passwords should be moved or
+// copied depending on the site's HSTS status. If a site has HSTS enabled, the
+// HTTP password is considered obsolete and will be replaced by an HTTPS
+// version. If HSTS is not enabled, some parts of the site might still be served
+// via HTTP, which is why the password is copied in this case.
 class HttpPasswordMigrator : public PasswordStoreConsumer {
  public:
-  enum class MigrationMode {
-    MOVE,  // HTTP credentials are deleted after migration to HTTPS.
-    COPY,  // HTTP credentials are kept after migration to HTTPS.
-  };
-
   // API to be implemented by an embedder of HttpPasswordMigrator.
   class Consumer {
    public:
@@ -43,8 +43,7 @@
 
   // |https_origin| should specify a valid HTTPS URL.
   HttpPasswordMigrator(const GURL& https_origin,
-                       MigrationMode mode,
-                       PasswordStore* password_store,
+                       const PasswordManagerClient* client,
                        Consumer* consumer);
   ~HttpPasswordMigrator() override;
 
@@ -52,10 +51,29 @@
   void OnGetPasswordStoreResults(
       std::vector<std::unique_ptr<autofill::PasswordForm>> results) override;
 
+  // Callback for |PasswordManagerClient::PostHSTSQueryForHost|.
+  void OnHSTSQueryResult(bool is_hsts);
+
  private:
-  const MigrationMode mode_;
+  enum class MigrationMode {
+    MOVE,  // HTTP credentials are deleted after migration to HTTPS.
+    COPY,  // HTTP credentials are kept after migration to HTTPS.
+  };
+
+  void ProcessPasswordStoreResults();
+
+  const PasswordManagerClient* const client_;
   Consumer* consumer_;
-  PasswordStore* password_store_;
+
+  // |ProcessPasswordStoreResults| requires that both |OnHSTSQueryResult| and
+  // |OnGetPasswordStoreResults| have returned. Since this can happen in an
+  // arbitrary order, boolean flags are introduced to indicate completion. Only
+  // if both are set to true |ProcessPasswordStoreResults| gets called.
+  bool got_hsts_query_result_ = false;
+  bool got_password_store_results_ = false;
+  MigrationMode mode_;
+  std::vector<std::unique_ptr<autofill::PasswordForm>> results_;
+  base::ThreadChecker thread_checker_;
 
   DISALLOW_COPY_AND_ASSIGN(HttpPasswordMigrator);
 };
diff --git a/components/password_manager/core/browser/http_password_migrator_unittest.cc b/components/password_manager/core/browser/http_password_migrator_unittest.cc
index 76cc593..084daa7 100644
--- a/components/password_manager/core/browser/http_password_migrator_unittest.cc
+++ b/components/password_manager/core/browser/http_password_migrator_unittest.cc
@@ -8,6 +8,7 @@
 #include "base/message_loop/message_loop.h"
 #include "base/strings/utf_string_conversions.h"
 #include "components/password_manager/core/browser/mock_password_store.h"
+#include "components/password_manager/core/browser/stub_password_manager_client.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -15,9 +16,10 @@
 namespace {
 
 using autofill::PasswordForm;
-using testing::_;
 using testing::ElementsAre;
 using testing::Pointee;
+using testing::SaveArg;
+using testing::_;
 
 constexpr char kTestHttpsURL[] = "https://example.org/";
 constexpr char kTestHttpURL[] = "http://example.org/";
@@ -74,49 +76,71 @@
   }
 };
 
+class MockPasswordManagerClient : public StubPasswordManagerClient {
+ public:
+  explicit MockPasswordManagerClient(PasswordStore* store) : store_(store) {}
+
+  PasswordStore* GetPasswordStore() const override { return store_; }
+  MOCK_CONST_METHOD2(PostHSTSQueryForHost,
+                     void(const GURL&, const HSTSCallback& callback));
+
+ private:
+  PasswordStore* store_;
+
+  DISALLOW_COPY_AND_ASSIGN(MockPasswordManagerClient);
+};
+
+}  // namespace
+
 class HttpPasswordMigratorTest : public testing::Test {
  public:
-  HttpPasswordMigratorTest() {
-    mock_store_ = new testing::StrictMock<MockPasswordStore>;
-  }
+  HttpPasswordMigratorTest()
+      : mock_store_(new testing::StrictMock<MockPasswordStore>),
+        client_(mock_store_.get()) {}
 
   ~HttpPasswordMigratorTest() override { mock_store_->ShutdownOnUIThread(); }
 
   MockConsumer& consumer() { return consumer_; }
   MockPasswordStore& store() { return *mock_store_; }
+  MockPasswordManagerClient& client() { return client_; }
 
  protected:
-  void TestEmptyStore(HttpPasswordMigrator::MigrationMode mode);
-  void TestFullStore(HttpPasswordMigrator::MigrationMode mode);
+  void TestEmptyStore(bool is_hsts);
+  void TestFullStore(bool is_hsts);
 
  private:
   base::MessageLoop message_loop_;  // Used by mock_store_.
   MockConsumer consumer_;
   scoped_refptr<MockPasswordStore> mock_store_;
+  MockPasswordManagerClient client_;
 
   DISALLOW_COPY_AND_ASSIGN(HttpPasswordMigratorTest);
 };
 
-void HttpPasswordMigratorTest::TestEmptyStore(
-    HttpPasswordMigrator::MigrationMode mode) {
+void HttpPasswordMigratorTest::TestEmptyStore(bool is_hsts) {
   PasswordStore::FormDigest form(autofill::PasswordForm::SCHEME_HTML,
                                  kTestHttpURL, GURL(kTestHttpURL));
   EXPECT_CALL(store(), GetLogins(form, _));
-  HttpPasswordMigrator migrator(GURL(kTestHttpsURL), mode, &store(),
-                                &consumer());
+  PasswordManagerClient::HSTSCallback callback;
+  EXPECT_CALL(client(), PostHSTSQueryForHost(GURL(kTestHttpsURL), _))
+      .WillOnce(SaveArg<1>(&callback));
+  HttpPasswordMigrator migrator(GURL(kTestHttpsURL), &client(), &consumer());
+  callback.Run(is_hsts);
 
   EXPECT_CALL(consumer(), ProcessForms(std::vector<autofill::PasswordForm*>()));
   migrator.OnGetPasswordStoreResults(
       std::vector<std::unique_ptr<autofill::PasswordForm>>());
 }
 
-void HttpPasswordMigratorTest::TestFullStore(
-    HttpPasswordMigrator::MigrationMode mode) {
+void HttpPasswordMigratorTest::TestFullStore(bool is_hsts) {
   PasswordStore::FormDigest form_digest(autofill::PasswordForm::SCHEME_HTML,
                                         kTestHttpURL, GURL(kTestHttpURL));
   EXPECT_CALL(store(), GetLogins(form_digest, _));
-  HttpPasswordMigrator migrator(GURL(kTestHttpsURL), mode, &store(),
-                                &consumer());
+  PasswordManagerClient::HSTSCallback callback;
+  EXPECT_CALL(client(), PostHSTSQueryForHost(GURL(kTestHttpsURL), _))
+      .WillOnce(SaveArg<1>(&callback));
+  HttpPasswordMigrator migrator(GURL(kTestHttpsURL), &client(), &consumer());
+  callback.Run(is_hsts);
 
   PasswordForm form = CreateTestForm();
   PasswordForm psl_form = CreateTestPSLForm();
@@ -126,8 +150,7 @@
   expected_form.signon_realm = expected_form.origin.spec();
 
   EXPECT_CALL(store(), AddLogin(expected_form));
-  EXPECT_CALL(store(), RemoveLogin(form))
-      .Times(mode == HttpPasswordMigrator::MigrationMode::MOVE);
+  EXPECT_CALL(store(), RemoveLogin(form)).Times(is_hsts);
   EXPECT_CALL(consumer(), ProcessForms(ElementsAre(Pointee(expected_form))));
   std::vector<std::unique_ptr<autofill::PasswordForm>> results;
   results.push_back(base::MakeUnique<PasswordForm>(psl_form));
@@ -136,21 +159,20 @@
   migrator.OnGetPasswordStoreResults(std::move(results));
 }
 
-TEST_F(HttpPasswordMigratorTest, EmptyStoreWithMove) {
-  TestEmptyStore(HttpPasswordMigrator::MigrationMode::MOVE);
+TEST_F(HttpPasswordMigratorTest, EmptyStoreWithHSTS) {
+  TestEmptyStore(true);
 }
 
-TEST_F(HttpPasswordMigratorTest, EmptyStoreWithCopy) {
-  TestEmptyStore(HttpPasswordMigrator::MigrationMode::COPY);
+TEST_F(HttpPasswordMigratorTest, EmptyStoreWithoutHSTS) {
+  TestEmptyStore(false);
 }
 
-TEST_F(HttpPasswordMigratorTest, FullStoreWithMove) {
-  TestFullStore(HttpPasswordMigrator::MigrationMode::MOVE);
+TEST_F(HttpPasswordMigratorTest, FullStoreWithHSTS) {
+  TestFullStore(true);
 }
 
-TEST_F(HttpPasswordMigratorTest, FullStoreWithCopy) {
-  TestFullStore(HttpPasswordMigrator::MigrationMode::COPY);
+TEST_F(HttpPasswordMigratorTest, FullStoreWithoutHSTS) {
+  TestFullStore(false);
 }
 
-}  // namespace
 }  // namespace password_manager
diff --git a/components/password_manager/core/browser/obsolete_http_cleaner.cc b/components/password_manager/core/browser/obsolete_http_cleaner.cc
index c1daec4..06536ddc 100644
--- a/components/password_manager/core/browser/obsolete_http_cleaner.cc
+++ b/components/password_manager/core/browser/obsolete_http_cleaner.cc
@@ -9,6 +9,7 @@
 #include <tuple>
 
 #include "base/logging.h"
+#include "base/memory/ref_counted.h"
 #include "components/autofill/core/common/password_form.h"
 #include "components/password_manager/core/browser/password_manager_client.h"
 #include "components/password_manager/core/browser/password_store.h"
@@ -31,6 +32,20 @@
   return result;
 }
 
+void RemoveLoginIfHSTS(const scoped_refptr<PasswordStore>& store,
+                       const PasswordForm& form,
+                       bool is_hsts) {
+  if (is_hsts)
+    store->RemoveLogin(form);
+}
+
+void RemoveSiteStatsIfHSTS(const scoped_refptr<PasswordStore>& store,
+                           const InteractionsStats& stats,
+                           bool is_hsts) {
+  if (is_hsts)
+    store->RemoveSiteStats(stats.origin_domain);
+}
+
 }  // namespace
 
 ObsoleteHttpCleaner::ObsoleteHttpCleaner(const PasswordManagerClient* client)
@@ -68,25 +83,19 @@
   // Remove blacklisted HTTP forms from the password store when HSTS is active
   // for the given host.
   for (const auto& form : blacklisted_http_forms) {
-    if (client_->IsHSTSActiveForHost(form->origin))
-      client_->GetPasswordStore()->RemoveLogin(*form);
+    client_->PostHSTSQueryForHost(
+        form->origin,
+        base::Bind(RemoveLoginIfHSTS,
+                   make_scoped_refptr(client_->GetPasswordStore()), *form));
   }
 
   // Return early if there are no non-blacklisted HTTP forms.
   if (results.empty())
     return;
 
-  // Ignore non HSTS forms.
-  https_forms.erase(
-      std::remove_if(std::begin(https_forms), std::end(https_forms),
-                     [this](const std::unique_ptr<PasswordForm>& form) {
-                       return !client_->IsHSTSActiveForHost(form->origin);
-                     }),
-      std::end(https_forms));
-
-  // Sort HSTS forms according to custom comparison function. Consider two forms
-  // equivalent if they have the same host, as well as the same username and
-  // password.
+  // Sort HTTPS forms according to custom comparison function. Consider two
+  // forms equivalent if they have the same host, as well as the same username
+  // and password.
   const auto form_cmp = [](const std::unique_ptr<PasswordForm>& lhs,
                            const std::unique_ptr<PasswordForm>& rhs) {
     return std::forward_as_tuple(lhs->origin.host_piece(), lhs->username_value,
@@ -98,20 +107,27 @@
   std::sort(std::begin(https_forms), std::end(https_forms), form_cmp);
 
   // Iterate through HTTP forms and remove them from the password store if there
-  // exists an equivalent HSTS form.
+  // exists an equivalent HTTPS form that has HSTS enabled.
   for (const auto& form : results) {
     if (std::binary_search(std::begin(https_forms), std::end(https_forms), form,
-                           form_cmp))
-      client_->GetPasswordStore()->RemoveLogin(*form);
+                           form_cmp)) {
+      client_->PostHSTSQueryForHost(
+          form->origin,
+          base::Bind(RemoveLoginIfHSTS,
+                     make_scoped_refptr(client_->GetPasswordStore()), *form));
+    }
   }
 }
 
 void ObsoleteHttpCleaner::OnGetSiteStatistics(
     std::vector<InteractionsStats> stats) {
   for (const auto& stat : stats) {
-    if (stat.origin_domain.SchemeIs(url::kHttpScheme) &&
-        client_->IsHSTSActiveForHost(stat.origin_domain))
-      client_->GetPasswordStore()->RemoveSiteStats(stat.origin_domain);
+    if (stat.origin_domain.SchemeIs(url::kHttpScheme)) {
+      client_->PostHSTSQueryForHost(
+          stat.origin_domain,
+          base::Bind(RemoveSiteStatsIfHSTS,
+                     make_scoped_refptr(client_->GetPasswordStore()), stat));
+    }
   }
 }
 
diff --git a/components/password_manager/core/browser/obsolete_http_cleaner_unittest.cc b/components/password_manager/core/browser/obsolete_http_cleaner_unittest.cc
index 7ae1fd7..22e81ee 100644
--- a/components/password_manager/core/browser/obsolete_http_cleaner_unittest.cc
+++ b/components/password_manager/core/browser/obsolete_http_cleaner_unittest.cc
@@ -18,6 +18,8 @@
 
 using autofill::PasswordForm;
 using testing::Return;
+using testing::SaveArg;
+using testing::_;
 
 namespace password_manager {
 
@@ -75,7 +77,8 @@
   explicit MockPasswordManagerClient(PasswordStore* store) : store_(store) {}
 
   PasswordStore* GetPasswordStore() const override { return store_; }
-  MOCK_CONST_METHOD1(IsHSTSActiveForHost, bool(const GURL&));
+  MOCK_CONST_METHOD2(PostHSTSQueryForHost,
+                     void(const GURL&, const HSTSCallback& callback));
 
  private:
   PasswordStore* store_;
@@ -130,13 +133,18 @@
     PasswordForm form =
         test_case.is_http ? CreateTestHTTPForm() : CreateTestHTTPSForm();
     form.blacklisted_by_user = test_case.is_blacklisted;
-    if (test_case.is_http && test_case.is_blacklisted) {
-      EXPECT_CALL(client(), IsHSTSActiveForHost(form.origin))
-          .WillOnce(Return(test_case.is_hsts));
+    PasswordManagerClient::HSTSCallback callback;
+    const bool should_expect_hsts_query =
+        test_case.is_http && test_case.is_blacklisted;
+    if (should_expect_hsts_query) {
+      EXPECT_CALL(client(), PostHSTSQueryForHost(form.origin, _))
+          .WillOnce(SaveArg<1>(&callback));
     }
 
-    EXPECT_CALL(store(), RemoveLogin(form)).Times(test_case.is_deleted);
     cleaner.OnGetPasswordStoreResults(MakeResults({form}));
+    EXPECT_CALL(store(), RemoveLogin(form)).Times(test_case.is_deleted);
+    if (should_expect_hsts_query)
+      callback.Run(test_case.is_hsts);
   }
 }
 
@@ -188,10 +196,18 @@
           https_form.password_value + base::ASCIIToUTF16("-different");
     }
 
-    EXPECT_CALL(client(), IsHSTSActiveForHost(https_form.origin))
-        .WillOnce(Return(test_case.is_hsts));
-    EXPECT_CALL(store(), RemoveLogin(http_form)).Times(test_case.is_deleted);
+    PasswordManagerClient::HSTSCallback callback;
+    const bool should_expect_hsts_query =
+        test_case.same_host && test_case.same_user && test_case.same_pass;
+    if (should_expect_hsts_query) {
+      EXPECT_CALL(client(), PostHSTSQueryForHost(http_form.origin, _))
+          .WillOnce(SaveArg<1>(&callback));
+    }
+
     cleaner.OnGetPasswordStoreResults(MakeResults({http_form, https_form}));
+    EXPECT_CALL(store(), RemoveLogin(http_form)).Times(test_case.is_deleted);
+    if (should_expect_hsts_query)
+      callback.Run(test_case.is_hsts);
   }
 }
 
@@ -218,14 +234,22 @@
 
     InteractionsStats stats =
         test_case.is_http ? CreateTestHTTPStats() : CreateTestHTTPSStats();
-    if (test_case.is_http) {
-      EXPECT_CALL(client(), IsHSTSActiveForHost(stats.origin_domain))
-          .WillOnce(Return(test_case.is_hsts));
+    PasswordManagerClient::HSTSCallback callback;
+    const bool should_expect_hsts_query = test_case.is_http;
+    if (should_expect_hsts_query) {
+      EXPECT_CALL(client(), PostHSTSQueryForHost(stats.origin_domain, _))
+          .WillOnce(SaveArg<1>(&callback));
     }
 
+    cleaner.OnGetSiteStatistics({stats});
     EXPECT_CALL(store(), RemoveSiteStatsImpl(stats.origin_domain))
         .Times(test_case.is_deleted);
-    cleaner.OnGetSiteStatistics({stats});
+    if (should_expect_hsts_query)
+      callback.Run(test_case.is_hsts);
+
+    // We expect a call to |RemoveSiteStatsImpl| which is a async task posted
+    // from |PasswordStore::RemoveSiteStats|. Hence the following line is
+    // necessary to ensure |RemoveSiteStatsImpl| gets called.
     base::RunLoop().RunUntilIdle();
   }
 }
diff --git a/components/password_manager/core/browser/password_manager_client.cc b/components/password_manager/core/browser/password_manager_client.cc
index 8e61e49..93bed56 100644
--- a/components/password_manager/core/browser/password_manager_client.cc
+++ b/components/password_manager/core/browser/password_manager_client.cc
@@ -15,8 +15,10 @@
   return true;
 }
 
-bool PasswordManagerClient::IsHSTSActiveForHost(const GURL& origin) const {
-  return false;
+void PasswordManagerClient::PostHSTSQueryForHost(
+    const GURL& origin,
+    const HSTSCallback& callback) const {
+  callback.Run(false);
 }
 
 bool PasswordManagerClient::OnCredentialManagerUsed() {
diff --git a/components/password_manager/core/browser/password_manager_client.h b/components/password_manager/core/browser/password_manager_client.h
index f520d36..8edd18b 100644
--- a/components/password_manager/core/browser/password_manager_client.h
+++ b/components/password_manager/core/browser/password_manager_client.h
@@ -38,6 +38,7 @@
 // environment.
 class PasswordManagerClient {
  public:
+  using HSTSCallback = base::Callback<void(bool)>;
   using CredentialsCallback =
       base::Callback<void(const autofill::PasswordForm*)>;
 
@@ -53,9 +54,11 @@
   // password manager is disabled, or in the presence of SSL errors on a page.
   virtual bool IsFillingEnabledForCurrentPage() const;
 
-  // Checks whether HTTP Strict Transport Security (HSTS) is active for the host
-  // of the given origin.
-  virtual bool IsHSTSActiveForHost(const GURL& origin) const;
+  // Checks asynchronously whether HTTP Strict Transport Security (HSTS) is
+  // active for the host of the given origin. Notifies |callback| with the
+  // result on the calling thread.
+  virtual void PostHSTSQueryForHost(const GURL& origin,
+                                    const HSTSCallback& callback) const;
 
   // Checks if the Credential Manager API is allowed to run on the page. It's
   // not allowed while prerendering and the pre-rendered WebContents will be
diff --git a/components/password_manager/core/browser/password_manager_metrics_util.cc b/components/password_manager/core/browser/password_manager_metrics_util.cc
index 2bce4df..642f030 100644
--- a/components/password_manager/core/browser/password_manager_metrics_util.cc
+++ b/components/password_manager/core/browser/password_manager_metrics_util.cc
@@ -115,6 +115,11 @@
   UMA_HISTOGRAM_COUNTS_100("PasswordManager.HttpPasswordMigrationCount", count);
 }
 
+void LogHttpPasswordMigrationMode(HttpPasswordMigrationMode mode) {
+  UMA_HISTOGRAM_ENUMERATION("PasswordManager.HttpPasswordMigrationMode", mode,
+                            HTTP_PASSWORD_MIGRATION_MODE_COUNT);
+}
+
 void LogAccountChooserUsability(AccountChooserUsabilityMetric usability,
                                 int count_empty_icons,
                                 int count_accounts) {
diff --git a/components/password_manager/core/browser/password_manager_metrics_util.h b/components/password_manager/core/browser/password_manager_metrics_util.h
index 040a3be6..2fb1b73 100644
--- a/components/password_manager/core/browser/password_manager_metrics_util.h
+++ b/components/password_manager/core/browser/password_manager_metrics_util.h
@@ -173,6 +173,13 @@
   CREDENTIAL_MANAGER_GET_UNMEDIATED
 };
 
+// Metrics: "PasswordManager.HttpPasswordMigrationMode"
+enum HttpPasswordMigrationMode {
+  HTTP_PASSWORD_MIGRATION_MODE_MOVE,
+  HTTP_PASSWORD_MIGRATION_MODE_COPY,
+  HTTP_PASSWORD_MIGRATION_MODE_COUNT
+};
+
 enum PasswordReusePasswordFieldDetected {
   NO_PASSWORD_FIELD,
   HAS_PASSWORD_FIELD,
@@ -229,6 +236,9 @@
 // Logs number of passwords migrated from HTTP to HTTPS.
 void LogCountHttpMigratedPasswords(int count);
 
+// Logs mode of HTTP password migration.
+void LogHttpPasswordMigrationMode(HttpPasswordMigrationMode mode);
+
 // Log if the account chooser has empty username or duplicate usernames. In
 // addition record number of the placeholder avatars and total number of rows.
 void LogAccountChooserUsability(AccountChooserUsabilityMetric usability,
diff --git a/content/renderer/gpu/gpu_benchmarking_extension.cc b/content/renderer/gpu/gpu_benchmarking_extension.cc
index 23b9771..4b8fa55 100644
--- a/content/renderer/gpu/gpu_benchmarking_extension.cc
+++ b/content/renderer/gpu/gpu_benchmarking_extension.cc
@@ -61,6 +61,13 @@
 #include "ui/gfx/codec/png_codec.h"
 #include "v8/include/v8.h"
 
+#if defined(OS_WIN) && !defined(NDEBUG)
+#include <XpsObjectModel.h>
+#include "base/win/scoped_comptr.h"
+#include "skia/ext/skia_encode_image.h"
+#include "ui/gfx/codec/skia_image_encoder_adapter.h"
+#endif
+
 using blink::WebCanvas;
 using blink::WebLocalFrame;
 using blink::WebImageCache;
@@ -513,6 +520,31 @@
     doc->close();
   }
 }
+
+// This function is only used for correctness testing of this experimental
+// feature; no need for it in release builds.
+// Also note:  You must execute Chrome with `--no-sandbox` and
+// `--enable-gpu-benchmarking` for this to work.
+#if defined(OS_WIN) && !defined(NDEBUG)
+static sk_sp<SkDocument> MakeXPSDocument(SkWStream* s) {
+  // Hand Skia an image encoder, needed for XPS backend.
+  skia::SetImageEncoder(&gfx::EncodeSkiaImage);
+
+  // I am not sure why this hasn't been initialized yet.
+  (void)CoInitializeEx(nullptr,
+                       COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
+  // In non-sandboxed mode, we will need to create and hold on to the
+  // factory before entering the sandbox.
+  base::win::ScopedComPtr<IXpsOMObjectFactory> factory;
+  HRESULT hr = factory.CreateInstance(CLSID_XpsOMObjectFactory, nullptr,
+                                      CLSCTX_INPROC_SERVER);
+  if (FAILED(hr) || !factory) {
+    LOG(ERROR) << "CoCreateInstance(CLSID_XpsOMObjectFactory, ...) failed:"
+               << logging::SystemErrorCodeToString(hr);
+  }
+  return SkDocument::MakeXPS(s, factory.get());
+}
+#endif
 }  // namespace
 
 gin::WrapperInfo GpuBenchmarking::kWrapperInfo = {gin::kEmbedderNativeGin};
@@ -600,13 +632,18 @@
 
 void GpuBenchmarking::PrintPagesToSkPictures(v8::Isolate* isolate,
                                              const std::string& filename) {
-    PrintDocumentTofile(isolate, filename, &SkMakeMultiPictureDocument);
+  PrintDocumentTofile(isolate, filename, &SkMakeMultiPictureDocument);
 }
 
 void GpuBenchmarking::PrintPagesToXPS(v8::Isolate* isolate,
                                       const std::string& filename) {
-    PrintDocumentTofile(isolate, filename,
-                        [](SkWStream* s) { return SkDocument::MakeXPS(s); });
+#if defined(OS_WIN) && !defined(NDEBUG)
+  PrintDocumentTofile(isolate, filename, &MakeXPSDocument);
+#else
+  std::string msg("PrintPagesToXPS is unsupported.");
+  isolate->ThrowException(v8::Exception::Error(v8::String::NewFromUtf8(
+      isolate, msg.c_str(), v8::String::kNormalString, msg.length())));
+#endif
 }
 
 void GpuBenchmarking::PrintToSkPicture(v8::Isolate* isolate,
diff --git a/ios/chrome/browser/tabs/BUILD.gn b/ios/chrome/browser/tabs/BUILD.gn
index 7fb895df..9a97750 100644
--- a/ios/chrome/browser/tabs/BUILD.gn
+++ b/ios/chrome/browser/tabs/BUILD.gn
@@ -125,6 +125,8 @@
     "tab_model_observers_bridge.mm",
     "tab_model_selected_tab_observer.h",
     "tab_model_selected_tab_observer.mm",
+    "tab_model_web_state_list_delegate.h",
+    "tab_model_web_state_list_delegate.mm",
     "tab_parenting_observer.h",
     "tab_parenting_observer.mm",
   ]
diff --git a/ios/chrome/browser/tabs/tab.mm b/ios/chrome/browser/tabs/tab.mm
index 506298d..6627920e 100644
--- a/ios/chrome/browser/tabs/tab.mm
+++ b/ios/chrome/browser/tabs/tab.mm
@@ -527,12 +527,12 @@
 
     webStateImpl_.reset(static_cast<web::WebStateImpl*>(webState.release()));
     webStateObserver_.reset(
-        new web::WebStateObserverBridge(webStateImpl_.get(), self));
+        new web::WebStateObserverBridge(self.webState, self));
     [self updateLastVisitedTimestamp];
 
     // Do not respect |attachTabHelpers| as this tab helper is required for
     // proper conversion from WebState to Tab.
-    LegacyTabHelper::CreateForWebState(webStateImpl_.get(), self);
+    LegacyTabHelper::CreateForWebState(self.webState, self);
 
     [self.webController setDelegate:self];
 
@@ -755,7 +755,7 @@
 }
 
 - (NSString*)title {
-  base::string16 title = webStateImpl_->GetTitle();
+  base::string16 title = self.webState->GetTitle();
   if (title.empty())
     title = l10n_util::GetStringUTF16(IDS_DEFAULT_TAB_TITLE);
   return base::SysUTF16ToNSString(title);
@@ -863,11 +863,11 @@
 }
 
 - (web::NavigationManager*)navigationManager {
-  return webStateImpl_ ? webStateImpl_->GetNavigationManager() : nullptr;
+  return self.webState ? self.webState->GetNavigationManager() : nullptr;
 }
 
 - (web::NavigationManagerImpl*)navigationManagerImpl {
-  return webStateImpl_ ? &(webStateImpl_->GetNavigationManagerImpl()) : nullptr;
+  return self.webState ? &(webStateImpl_->GetNavigationManagerImpl()) : nullptr;
 }
 
 // Swap out the existing session history with a new list of navigations. Forces
@@ -896,7 +896,7 @@
     [self.webController removeObserver:fullScreenController_];
     fullScreenController_.reset([[FullScreenController alloc]
          initWithDelegate:fullScreenControllerDelegate_
-        navigationManager:&(webStateImpl_->GetNavigationManagerImpl())
+        navigationManager:self.navigationManager
                 sessionID:self.tabId]);
     [self.webController addObserver:fullScreenController_];
     // If the content of the page was loaded without knowledge of the
@@ -954,11 +954,9 @@
   // The check for fullScreenControllerDelegate is necessary to avoid recreating
   // a FullScreenController during teardown.
   if (!fullScreenController_ && fullScreenControllerDelegate) {
-    NavigationManagerImpl* navigationManager =
-        &(webStateImpl_->GetNavigationManagerImpl());
     fullScreenController_.reset([[FullScreenController alloc]
          initWithDelegate:fullScreenControllerDelegate
-        navigationManager:navigationManager
+        navigationManager:self.navigationManager
                 sessionID:self.tabId]);
     if (fullScreenController_) {
       [self.webController addObserver:fullScreenController_];
@@ -1227,11 +1225,6 @@
   // Reset association with the webController.
   [self.webController setDelegate:nil];
 
-  webStateImpl_->ClearTransientContentView();
-  // Terminate the network activity before notifying the parent model, because
-  // the parent model may initiate the request context destruction.
-  [self terminateNetworkActivity];
-
   // Cancel any queued dialogs.
   [self.dialogDelegate cancelDialogForTab:self];
 
@@ -1253,7 +1246,7 @@
   base::scoped_nsobject<Tab> kungFuDeathGrip([self retain]);
   [parentTabModel_ didCloseTab:self];  // Inform parent of tab closure.
 
-  LegacyTabHelper::RemoveFromWebState(webStateImpl_.get());
+  LegacyTabHelper::RemoveFromWebState(self.webState);
   webStateImpl_.reset();
 }
 
diff --git a/ios/chrome/browser/tabs/tab_model.mm b/ios/chrome/browser/tabs/tab_model.mm
index a514950..a2d2d71 100644
--- a/ios/chrome/browser/tabs/tab_model.mm
+++ b/ios/chrome/browser/tabs/tab_model.mm
@@ -38,6 +38,7 @@
 #import "ios/chrome/browser/tabs/tab_model_observers_bridge.h"
 #import "ios/chrome/browser/tabs/tab_model_selected_tab_observer.h"
 #import "ios/chrome/browser/tabs/tab_model_synced_window_delegate.h"
+#import "ios/chrome/browser/tabs/tab_model_web_state_list_delegate.h"
 #import "ios/chrome/browser/tabs/tab_parenting_observer.h"
 #import "ios/chrome/browser/xcallback_parameters.h"
 #import "ios/shared/chrome/browser/tabs/web_state_list.h"
@@ -147,8 +148,11 @@
 @end
 
 @interface TabModel ()<TabUsageRecorderDelegate> {
+  // Delegate for the WebStateList.
+  std::unique_ptr<WebStateListDelegate> _webStateListDelegate;
+
   // Underlying shared model implementation.
-  WebStateList _webStateList;
+  std::unique_ptr<WebStateList> _webStateList;
 
   // Helper providing NSFastEnumeration implementation over the WebStateList.
   base::scoped_nsobject<WebStateListFastEnumerationHelper>
@@ -235,7 +239,7 @@
 
   // Unregister all listeners before closing all the tabs.
   for (const auto& observerBridge : _observerBridges)
-    _webStateList.RemoveObserver(observerBridge.get());
+    _webStateList->RemoveObserver(observerBridge.get());
   _observerBridges.clear();
 
   // Make sure the tabs do clean after themselves. It is important for
@@ -251,14 +255,14 @@
 #pragma mark - Public methods
 
 - (Tab*)currentTab {
-  web::WebState* webState = _webStateList.GetActiveWebState();
+  web::WebState* webState = _webStateList->GetActiveWebState();
   return webState ? LegacyTabHelper::GetTabForWebState(webState) : nil;
 }
 
 - (void)setCurrentTab:(Tab*)newTab {
-  int indexOfTab = _webStateList.GetIndexOfWebState(newTab.webState);
+  int indexOfTab = _webStateList->GetIndexOfWebState(newTab.webState);
   DCHECK_NE(indexOfTab, WebStateList::kInvalidIndex);
-  _webStateList.ActivateWebStateAt(indexOfTab);
+  _webStateList->ActivateWebStateAt(indexOfTab);
 }
 
 - (TabModelSyncedWindowDelegate*)syncedWindowDelegate {
@@ -274,12 +278,12 @@
 }
 
 - (BOOL)isEmpty {
-  return _webStateList.empty();
+  return _webStateList->empty();
 }
 
 - (NSUInteger)count {
-  DCHECK_GE(_webStateList.count(), 0);
-  return static_cast<NSUInteger>(_webStateList.count());
+  DCHECK_GE(_webStateList->count(), 0);
+  return static_cast<NSUInteger>(_webStateList->count());
 }
 
 - (instancetype)initWithSessionWindow:(SessionWindowIOS*)window
@@ -289,8 +293,13 @@
     _tabRetainer.reset([[NSMutableSet alloc] init]);
     _observers.reset([[TabModelObservers observers] retain]);
 
+    _webStateListDelegate =
+        base::MakeUnique<TabModelWebStateListDelegate>(self);
+    _webStateList = base::MakeUnique<WebStateList>(
+        _webStateListDelegate.get(), WebStateList::WebStateBorrowed);
+
     _fastEnumerationHelper.reset([[WebStateListFastEnumerationHelper alloc]
-        initWithWebStateList:&_webStateList
+        initWithWebStateList:_webStateList.get()
                 proxyFactory:[[TabModelWebStateProxyFactory alloc] init]]);
 
     _browserState = browserState;
@@ -331,7 +340,7 @@
     _observerBridges.push_back(std::move(webStateListMetricsObserver));
 
     for (const auto& observerBridge : _observerBridges)
-      _webStateList.AddObserver(observerBridge.get());
+      _webStateList->AddObserver(observerBridge.get());
 
     if (window) {
       DCHECK([_observers empty]);
@@ -378,7 +387,7 @@
 - (void)saveSessionImmediately:(BOOL)immediately {
   // Do nothing if there are tabs in the model but no selected tab. This is
   // a transitional state.
-  if ((!self.currentTab && _webStateList.count()) || !_browserState)
+  if ((!self.currentTab && _webStateList->count()) || !_browserState)
     return;
   [_sessionService saveWindow:self.windowForSavingSession
               forBrowserState:_browserState
@@ -388,11 +397,11 @@
 - (Tab*)tabAtIndex:(NSUInteger)index {
   DCHECK_LE(index, static_cast<NSUInteger>(INT_MAX));
   return LegacyTabHelper::GetTabForWebState(
-      _webStateList.GetWebStateAt(static_cast<int>(index)));
+      _webStateList->GetWebStateAt(static_cast<int>(index)));
 }
 
 - (NSUInteger)indexOfTab:(Tab*)tab {
-  int index = _webStateList.GetIndexOfWebState(tab.webState);
+  int index = _webStateList->GetIndexOfWebState(tab.webState);
   if (index == WebStateList::kInvalidIndex)
     return NSNotFound;
 
@@ -403,12 +412,12 @@
 - (Tab*)nextTabWithOpener:(Tab*)tab afterTab:(Tab*)afterTab {
   int startIndex = WebStateList::kInvalidIndex;
   if (afterTab)
-    startIndex = _webStateList.GetIndexOfWebState(afterTab.webState);
+    startIndex = _webStateList->GetIndexOfWebState(afterTab.webState);
 
   if (startIndex == WebStateList::kInvalidIndex)
-    startIndex = _webStateList.GetIndexOfWebState(tab.webState);
+    startIndex = _webStateList->GetIndexOfWebState(tab.webState);
 
-  const int index = _webStateList.GetIndexOfNextWebStateOpenedBy(
+  const int index = _webStateList->GetIndexOfNextWebStateOpenedBy(
       tab.webState, startIndex, false);
   if (index == WebStateList::kInvalidIndex)
     return nil;
@@ -418,11 +427,11 @@
 }
 
 - (Tab*)lastTabWithOpener:(Tab*)tab {
-  int startIndex = _webStateList.GetIndexOfWebState(tab.webState);
+  int startIndex = _webStateList->GetIndexOfWebState(tab.webState);
   if (startIndex == WebStateList::kInvalidIndex)
     return nil;
 
-  const int index = _webStateList.GetIndexOfLastWebStateOpenedBy(
+  const int index = _webStateList->GetIndexOfLastWebStateOpenedBy(
       tab.webState, startIndex, true);
   if (index == WebStateList::kInvalidIndex)
     return nil;
@@ -432,11 +441,11 @@
 }
 
 - (Tab*)openerOfTab:(Tab*)tab {
-  int index = _webStateList.GetIndexOfWebState(tab.webState);
+  int index = _webStateList->GetIndexOfWebState(tab.webState);
   if (index == WebStateList::kInvalidIndex)
     return nil;
 
-  web::WebState* opener = _webStateList.GetOpenerOfWebStateAt(index);
+  web::WebState* opener = _webStateList->GetOpenerOfWebStateAt(index);
   return opener ? LegacyTabHelper::GetTabForWebState(opener) : nil;
 }
 
@@ -517,12 +526,12 @@
 
   [_tabRetainer addObject:tab];
   if (index == TabModelConstants::kTabPositionAutomatically) {
-    _webStateList.AppendWebState(transition, tab.webState, parentTab.webState);
+    _webStateList->AppendWebState(transition, tab.webState, parentTab.webState);
   } else {
     DCHECK_LE(index, static_cast<NSUInteger>(INT_MAX));
     const int insertion_index = static_cast<int>(index);
-    _webStateList.InsertWebState(insertion_index, tab.webState,
-                                 parentTab.webState);
+    _webStateList->InsertWebState(insertion_index, tab.webState,
+                                  parentTab.webState);
   }
 
   // Persist the session due to a new tab being inserted. If this is a
@@ -554,15 +563,15 @@
 - (void)moveTab:(Tab*)tab toIndex:(NSUInteger)toIndex {
   DCHECK([_tabRetainer containsObject:tab]);
   DCHECK_LE(toIndex, static_cast<NSUInteger>(INT_MAX));
-  int fromIndex = _webStateList.GetIndexOfWebState(tab.webState);
-  _webStateList.MoveWebStateAt(fromIndex, static_cast<int>(toIndex));
+  int fromIndex = _webStateList->GetIndexOfWebState(tab.webState);
+  _webStateList->MoveWebStateAt(fromIndex, static_cast<int>(toIndex));
 }
 
 - (void)replaceTab:(Tab*)oldTab withTab:(Tab*)newTab {
   DCHECK([_tabRetainer containsObject:oldTab]);
   DCHECK(![_tabRetainer containsObject:newTab]);
 
-  int index = _webStateList.GetIndexOfWebState(oldTab.webState);
+  int index = _webStateList->GetIndexOfWebState(oldTab.webState);
   DCHECK_NE(index, WebStateList::kInvalidIndex);
   DCHECK_GE(index, 0);
 
@@ -577,7 +586,7 @@
   // object destroyed as expected, so it will fine to ignore the result then
   // too. See http://crbug.com/546222 for progress of changing the ownership
   // of the WebStates.
-  ignore_result(_webStateList.ReplaceWebStateAt(
+  ignore_result(_webStateList->ReplaceWebStateAt(
       index, newTab.webState, GetOpenerForTab(self, newTab).webState));
 
   [oldTab setParentTabModel:nil];
@@ -701,7 +710,7 @@
 - (void)didCloseTab:(Tab*)closedTab {
   DCHECK(closedTab);
   DCHECK([_tabRetainer containsObject:closedTab]);
-  int closedTabIndex = _webStateList.GetIndexOfWebState(closedTab.webState);
+  int closedTabIndex = _webStateList->GetIndexOfWebState(closedTab.webState);
   DCHECK_NE(closedTabIndex, WebStateList::kInvalidIndex);
   DCHECK_GE(closedTabIndex, 0);
 
@@ -734,7 +743,7 @@
   // object destroyed as expected, so it will fine to ignore the result then
   // too. See http://crbug.com/546222 for progress of changing the ownership
   // of the WebStates.
-  ignore_result(_webStateList.DetachWebStateAt(closedTabIndex));
+  ignore_result(_webStateList->DetachWebStateAt(closedTabIndex));
 
   if (needToSaveSession)
     [self saveSessionImmediately:NO];
@@ -832,7 +841,7 @@
   if (!sessions.count)
     return NO;
 
-  int oldCount = _webStateList.count();
+  int oldCount = _webStateList->count();
   DCHECK_GE(oldCount, 0);
 
   web::WebState::CreateParams params(_browserState);
@@ -861,18 +870,18 @@
   }
 
   DCHECK_EQ(sessions.count, [restoredTabs count]);
-  DCHECK_GT(_webStateList.count(), oldCount);
+  DCHECK_GT(_webStateList->count(), oldCount);
 
   // Fix openers now that all Tabs have been restored. Only look for an opener
   // Tab in the newly restored Tabs and not in the already open Tabs.
-  for (int index = oldCount; index < _webStateList.count(); ++index) {
+  for (int index = oldCount; index < _webStateList->count(); ++index) {
     DCHECK_GE(index, oldCount);
     NSUInteger tabIndex = static_cast<NSUInteger>(index - oldCount);
     Tab* tab = [restoredTabs objectAtIndex:tabIndex];
     Tab* opener = GetOpenerForTab(restoredTabs.get(), tab);
     if (opener) {
       DCHECK(opener.webState);
-      _webStateList.SetOpenerOfWebStateAt(index, opener.webState);
+      _webStateList->SetOpenerOfWebStateAt(index, opener.webState);
     }
   }
 
@@ -884,7 +893,7 @@
 
     if (persistState && self.currentTab)
       [self.currentTab recordStateInHistory];
-    _webStateList.ActivateWebStateAt(static_cast<int>(selectedIndex));
+    _webStateList->ActivateWebStateAt(static_cast<int>(selectedIndex));
   }
 
   // If there was only one tab and it was the new tab page, clobber it.
@@ -899,9 +908,9 @@
   }
   if (_tabUsageRecorder) {
     NSMutableArray<Tab*>* restoredTabs =
-        [NSMutableArray arrayWithCapacity:_webStateList.count() - oldCount];
-    for (int index = oldCount; index < _webStateList.count(); ++index) {
-      web::WebState* webState = _webStateList.GetWebStateAt(index);
+        [NSMutableArray arrayWithCapacity:_webStateList->count() - oldCount];
+    for (int index = oldCount; index < _webStateList->count(); ++index) {
+      web::WebState* webState = _webStateList->GetWebStateAt(index);
       [restoredTabs addObject:LegacyTabHelper::GetTabForWebState(webState)];
     }
     _tabUsageRecorder->InitialRestoredTabs(self.currentTab, restoredTabs);
@@ -930,7 +939,7 @@
       &_clearPoliciesTaskTracker,
       web::WebThread::GetTaskRunnerForThread(web::WebThread::IO),
       web::BrowserState::GetCertificatePolicyCache(_browserState),
-      &_webStateList);
+      _webStateList.get());
 
   if (_tabUsageRecorder)
     _tabUsageRecorder->AppDidEnterBackground();
diff --git a/ios/chrome/browser/tabs/tab_model_web_state_list_delegate.h b/ios/chrome/browser/tabs/tab_model_web_state_list_delegate.h
new file mode 100644
index 0000000..d783b7e
--- /dev/null
+++ b/ios/chrome/browser/tabs/tab_model_web_state_list_delegate.h
@@ -0,0 +1,29 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_TABS_TAB_MODEL_WEB_STATE_LIST_DELEGATE_H_
+#define IOS_CHROME_BROWSER_TABS_TAB_MODEL_WEB_STATE_LIST_DELEGATE_H_
+
+#import "base/ios/weak_nsobject.h"
+#include "base/macros.h"
+#import "ios/shared/chrome/browser/tabs/web_state_list_delegate.h"
+
+@class TabModel;
+
+// WebStateList delegate for the old architecture.
+class TabModelWebStateListDelegate : public WebStateListDelegate {
+ public:
+  explicit TabModelWebStateListDelegate(TabModel* tab_model);
+  ~TabModelWebStateListDelegate() override;
+
+  // WebStateListDelegate implementation.
+  void WillAddWebState(web::WebState* web_state) override;
+
+ private:
+  base::WeakNSObject<TabModel> tab_model_;
+
+  DISALLOW_COPY_AND_ASSIGN(TabModelWebStateListDelegate);
+};
+
+#endif  // IOS_CHROME_BROWSER_TABS_TAB_MODEL_WEB_STATE_LIST_DELEGATE_H_
diff --git a/ios/chrome/browser/tabs/tab_model_web_state_list_delegate.mm b/ios/chrome/browser/tabs/tab_model_web_state_list_delegate.mm
new file mode 100644
index 0000000..66640bf
--- /dev/null
+++ b/ios/chrome/browser/tabs/tab_model_web_state_list_delegate.mm
@@ -0,0 +1,20 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/tabs/tab_model_web_state_list_delegate.h"
+
+#include "base/logging.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+TabModelWebStateListDelegate::TabModelWebStateListDelegate(TabModel* tab_model)
+    : tab_model_(tab_model) {
+  DCHECK(tab_model_);
+}
+
+TabModelWebStateListDelegate::~TabModelWebStateListDelegate() = default;
+
+void TabModelWebStateListDelegate::WillAddWebState(web::WebState* web_state) {}
diff --git a/ios/chrome/browser/ui/authentication/BUILD.gn b/ios/chrome/browser/ui/authentication/BUILD.gn
index c80542e..b41e78c 100644
--- a/ios/chrome/browser/ui/authentication/BUILD.gn
+++ b/ios/chrome/browser/ui/authentication/BUILD.gn
@@ -36,6 +36,7 @@
     "signin_interaction_controller.mm",
   ]
   deps = [
+    ":authentication_arc",
     ":resources",
     "//base",
     "//components/google/core/browser",
@@ -61,8 +62,6 @@
     "//ios/chrome/browser/ui/collection_view/cells",
     "//ios/chrome/browser/ui/colors",
     "//ios/chrome/browser/ui/commands",
-    "//ios/chrome/browser/ui/settings/cells",
-    "//ios/chrome/browser/ui/settings/utils",
     "//ios/chrome/browser/ui/util",
     "//ios/chrome/common",
     "//ios/public/provider/chrome/browser",
@@ -81,16 +80,40 @@
   ]
 }
 
+source_set("authentication_arc") {
+  configs += [ "//build/config/compiler:enable_arc" ]
+  sources = [
+    "account_control_item.h",
+    "account_control_item.mm",
+    "resized_avatar_cache.h",
+    "resized_avatar_cache.mm",
+  ]
+  deps = [
+    "//ios/chrome/browser/ui",
+    "//ios/chrome/browser/ui/collection_view/cells",
+    "//ios/chrome/browser/ui/colors",
+    "//ios/public/provider/chrome/browser",
+    "//ios/public/provider/chrome/browser/signin",
+  ]
+  libs = [
+    "CoreGraphics.framework",
+    "QuartzCore.framework",
+    "UIKit.framework",
+  ]
+}
+
 source_set("unit_tests") {
   configs += [ "//build/config/compiler:enable_arc" ]
   testonly = true
   sources = [
+    "account_control_item_unittest.mm",
     "authentication_flow_unittest.mm",
     "re_signin_infobar_delegate_unittest.mm",
     "signed_in_accounts_view_controller_unittest.mm",
   ]
   deps = [
     ":authentication",
+    ":authentication_arc",
     "//base",
     "//base/test:test_support",
     "//components/pref_registry",
@@ -101,9 +124,11 @@
     "//ios/chrome/browser/prefs:browser_prefs",
     "//ios/chrome/browser/signin",
     "//ios/chrome/browser/signin:test_support",
+    "//ios/chrome/browser/ui/colors",
     "//ios/chrome/browser/ui/commands",
     "//ios/chrome/test:test_support",
     "//ios/public/provider/chrome/browser/signin:test_support",
+    "//ios/third_party/material_components_ios",
     "//ios/web:test_support",
     "//testing/gtest",
     "//third_party/ocmock",
diff --git a/ios/chrome/browser/ui/settings/cells/account_control_item.h b/ios/chrome/browser/ui/authentication/account_control_item.h
similarity index 81%
rename from ios/chrome/browser/ui/settings/cells/account_control_item.h
rename to ios/chrome/browser/ui/authentication/account_control_item.h
index dadd84a..6715ee35 100644
--- a/ios/chrome/browser/ui/settings/cells/account_control_item.h
+++ b/ios/chrome/browser/ui/authentication/account_control_item.h
@@ -2,15 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_CELLS_ACCOUNT_CONTROL_ITEM_H_
-#define IOS_CHROME_BROWSER_UI_SETTINGS_CELLS_ACCOUNT_CONTROL_ITEM_H_
+#ifndef IOS_CHROME_BROWSER_UI_AUTHENTICATION_ACCOUNT_CONTROL_ITEM_H_
+#define IOS_CHROME_BROWSER_UI_AUTHENTICATION_ACCOUNT_CONTROL_ITEM_H_
 
 #import <UIKit/UIKit.h>
 
 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_item.h"
 #import "ios/third_party/material_components_ios/src/components/CollectionCells/src/MaterialCollectionCells.h"
 
-// Item for account settings view.
+// Item for account collection view and sign-in confirmation view.
 @interface AccountControlItem : CollectionViewItem
 
 @property(nonatomic, strong) UIImage* image;
@@ -33,4 +33,4 @@
 
 @end
 
-#endif  // IOS_CHROME_BROWSER_UI_SETTINGS_CELLS_ACCOUNT_CONTROL_ITEM_H_
+#endif  // IOS_CHROME_BROWSER_UI_AUTHENTICATION_ACCOUNT_CONTROL_ITEM_H_
diff --git a/ios/chrome/browser/ui/settings/cells/account_control_item.mm b/ios/chrome/browser/ui/authentication/account_control_item.mm
similarity index 98%
rename from ios/chrome/browser/ui/settings/cells/account_control_item.mm
rename to ios/chrome/browser/ui/authentication/account_control_item.mm
index ee2e86e..0ba7501 100644
--- a/ios/chrome/browser/ui/settings/cells/account_control_item.mm
+++ b/ios/chrome/browser/ui/authentication/account_control_item.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/ui/settings/cells/account_control_item.h"
+#import "ios/chrome/browser/ui/authentication/account_control_item.h"
 
 #import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h"
 #import "ios/third_party/material_components_ios/src/components/Typography/src/MaterialTypography.h"
diff --git a/ios/chrome/browser/ui/settings/cells/account_control_item_unittest.mm b/ios/chrome/browser/ui/authentication/account_control_item_unittest.mm
similarity index 97%
rename from ios/chrome/browser/ui/settings/cells/account_control_item_unittest.mm
rename to ios/chrome/browser/ui/authentication/account_control_item_unittest.mm
index eb0794d..f4aa9a8 100644
--- a/ios/chrome/browser/ui/settings/cells/account_control_item_unittest.mm
+++ b/ios/chrome/browser/ui/authentication/account_control_item_unittest.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/ui/settings/cells/account_control_item.h"
+#import "ios/chrome/browser/ui/authentication/account_control_item.h"
 
 #import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/ios/chrome/browser/ui/settings/utils/resized_avatar_cache.h b/ios/chrome/browser/ui/authentication/resized_avatar_cache.h
similarity index 80%
rename from ios/chrome/browser/ui/settings/utils/resized_avatar_cache.h
rename to ios/chrome/browser/ui/authentication/resized_avatar_cache.h
index 3a90a44..2d37e77 100644
--- a/ios/chrome/browser/ui/settings/utils/resized_avatar_cache.h
+++ b/ios/chrome/browser/ui/authentication/resized_avatar_cache.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_UTILS_RESIZED_AVATAR_CACHE_H_
-#define IOS_CHROME_BROWSER_UI_SETTINGS_UTILS_RESIZED_AVATAR_CACHE_H_
+#ifndef IOS_CHROME_BROWSER_UI_AUTHENTICATION_RESIZED_AVATAR_CACHE_H_
+#define IOS_CHROME_BROWSER_UI_AUTHENTICATION_RESIZED_AVATAR_CACHE_H_
 
 #import <Foundation/Foundation.h>
 
@@ -20,4 +20,4 @@
 - (UIImage*)resizedAvatarForIdentity:(ChromeIdentity*)identity;
 @end
 
-#endif  // IOS_CHROME_BROWSER_UI_SETTINGS_UTILS_RESIZED_AVATAR_CACHE_H_
+#endif  // IOS_CHROME_BROWSER_UI_AUTHENTICATION_RESIZED_AVATAR_CACHE_H_
diff --git a/ios/chrome/browser/ui/settings/utils/resized_avatar_cache.mm b/ios/chrome/browser/ui/authentication/resized_avatar_cache.mm
similarity index 97%
rename from ios/chrome/browser/ui/settings/utils/resized_avatar_cache.mm
rename to ios/chrome/browser/ui/authentication/resized_avatar_cache.mm
index b730b6a1b..b139b8d 100644
--- a/ios/chrome/browser/ui/settings/utils/resized_avatar_cache.mm
+++ b/ios/chrome/browser/ui/authentication/resized_avatar_cache.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/ui/settings/utils/resized_avatar_cache.h"
+#import "ios/chrome/browser/ui/authentication/resized_avatar_cache.h"
 
 #import "ios/chrome/browser/ui/uikit_ui_util.h"
 #import "ios/public/provider/chrome/browser/chrome_browser_provider.h"
diff --git a/ios/chrome/browser/ui/authentication/signed_in_accounts_view_controller.mm b/ios/chrome/browser/ui/authentication/signed_in_accounts_view_controller.mm
index 9f3a713..a34afc4 100644
--- a/ios/chrome/browser/ui/authentication/signed_in_accounts_view_controller.mm
+++ b/ios/chrome/browser/ui/authentication/signed_in_accounts_view_controller.mm
@@ -14,6 +14,7 @@
 #include "ios/chrome/browser/signin/authentication_service_factory.h"
 #include "ios/chrome/browser/signin/chrome_identity_service_observer_bridge.h"
 #include "ios/chrome/browser/signin/oauth2_token_service_factory.h"
+#import "ios/chrome/browser/ui/authentication/resized_avatar_cache.h"
 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_account_item.h"
 #import "ios/chrome/browser/ui/collection_view/collection_view_controller.h"
 #import "ios/chrome/browser/ui/collection_view/collection_view_model.h"
@@ -21,7 +22,6 @@
 #import "ios/chrome/browser/ui/commands/UIKit+ChromeExecuteCommand.h"
 #import "ios/chrome/browser/ui/commands/generic_chrome_command.h"
 #include "ios/chrome/browser/ui/commands/ios_command_ids.h"
-#import "ios/chrome/browser/ui/settings/utils/resized_avatar_cache.h"
 #import "ios/chrome/browser/ui/uikit_ui_util.h"
 #include "ios/chrome/grit/ios_chromium_strings.h"
 #include "ios/chrome/grit/ios_strings.h"
diff --git a/ios/chrome/browser/ui/authentication/signin_account_selector_view_controller.mm b/ios/chrome/browser/ui/authentication/signin_account_selector_view_controller.mm
index 31da8a8..822178a 100644
--- a/ios/chrome/browser/ui/authentication/signin_account_selector_view_controller.mm
+++ b/ios/chrome/browser/ui/authentication/signin_account_selector_view_controller.mm
@@ -9,12 +9,12 @@
 #import "base/mac/foundation_util.h"
 #import "base/mac/scoped_nsobject.h"
 #import "ios/chrome/browser/signin/chrome_identity_service_observer_bridge.h"
+#import "ios/chrome/browser/ui/authentication/resized_avatar_cache.h"
 #import "ios/chrome/browser/ui/collection_view/cells/MDCCollectionViewCell+Chrome.h"
 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_account_item.h"
 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_footer_item.h"
 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_text_item.h"
 #import "ios/chrome/browser/ui/collection_view/collection_view_model.h"
-#import "ios/chrome/browser/ui/settings/utils/resized_avatar_cache.h"
 #import "ios/chrome/browser/ui/uikit_ui_util.h"
 #include "ios/chrome/grit/ios_chromium_strings.h"
 #include "ios/chrome/grit/ios_strings.h"
diff --git a/ios/chrome/browser/ui/authentication/signin_confirmation_view_controller.mm b/ios/chrome/browser/ui/authentication/signin_confirmation_view_controller.mm
index 30c849c..6d583b6 100644
--- a/ios/chrome/browser/ui/authentication/signin_confirmation_view_controller.mm
+++ b/ios/chrome/browser/ui/authentication/signin_confirmation_view_controller.mm
@@ -12,10 +12,10 @@
 #include "components/google/core/browser/google_util.h"
 #include "ios/chrome/browser/application_context.h"
 #include "ios/chrome/browser/signin/chrome_identity_service_observer_bridge.h"
+#import "ios/chrome/browser/ui/authentication/account_control_item.h"
 #import "ios/chrome/browser/ui/collection_view/cells/MDCCollectionViewCell+Chrome.h"
 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_footer_item.h"
 #import "ios/chrome/browser/ui/collection_view/collection_view_model.h"
-#import "ios/chrome/browser/ui/settings/cells/account_control_item.h"
 #import "ios/chrome/browser/ui/uikit_ui_util.h"
 #import "ios/chrome/common/string_util.h"
 #include "ios/chrome/grit/ios_chromium_strings.h"
diff --git a/ios/chrome/browser/ui/bookmarks/BUILD.gn b/ios/chrome/browser/ui/bookmarks/BUILD.gn
index bbe8c4e..f0d473f 100644
--- a/ios/chrome/browser/ui/bookmarks/BUILD.gn
+++ b/ios/chrome/browser/ui/bookmarks/BUILD.gn
@@ -5,6 +5,28 @@
 source_set("bookmarks_arc") {
   configs += [ "//build/config/compiler:enable_arc" ]
   sources = [
+    "bookmark_collection_cells.h",
+    "bookmark_collection_cells.mm",
+    "bookmark_collection_view.h",
+    "bookmark_collection_view.mm",
+    "bookmark_collection_view_background.h",
+    "bookmark_collection_view_background.mm",
+    "bookmark_controller_factory.h",
+    "bookmark_controller_factory.mm",
+    "bookmark_edit_view_controller.h",
+    "bookmark_edit_view_controller.mm",
+    "bookmark_elevated_toolbar.h",
+    "bookmark_elevated_toolbar.mm",
+    "bookmark_extended_button.h",
+    "bookmark_extended_button.mm",
+    "bookmark_folder_collection_view.h",
+    "bookmark_folder_collection_view.mm",
+    "bookmark_folder_editor_view_controller.h",
+    "bookmark_folder_editor_view_controller.mm",
+    "bookmark_folder_table_view_cell.h",
+    "bookmark_folder_table_view_cell.mm",
+    "bookmark_folder_view_controller.h",
+    "bookmark_folder_view_controller.mm",
     "bookmark_home_handset_view_controller.h",
     "bookmark_home_handset_view_controller.mm",
     "bookmark_home_tablet_ntp_controller.h",
@@ -73,28 +95,6 @@
 
 source_set("bookmarks") {
   sources = [
-    "bookmark_collection_cells.h",
-    "bookmark_collection_cells.mm",
-    "bookmark_collection_view.h",
-    "bookmark_collection_view.mm",
-    "bookmark_collection_view_background.h",
-    "bookmark_collection_view_background.mm",
-    "bookmark_controller_factory.h",
-    "bookmark_controller_factory.mm",
-    "bookmark_edit_view_controller.h",
-    "bookmark_edit_view_controller.mm",
-    "bookmark_elevated_toolbar.h",
-    "bookmark_elevated_toolbar.mm",
-    "bookmark_extended_button.h",
-    "bookmark_extended_button.mm",
-    "bookmark_folder_collection_view.h",
-    "bookmark_folder_collection_view.mm",
-    "bookmark_folder_editor_view_controller.h",
-    "bookmark_folder_editor_view_controller.mm",
-    "bookmark_folder_table_view_cell.h",
-    "bookmark_folder_table_view_cell.mm",
-    "bookmark_folder_view_controller.h",
-    "bookmark_folder_view_controller.mm",
     "bookmark_home_primary_view.h",
     "bookmark_home_view_controller.h",
     "bookmark_home_view_controller.mm",
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_collection_cells.h b/ios/chrome/browser/ui/bookmarks/bookmark_collection_cells.h
index 4652ca0..196d108 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_collection_cells.h
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_collection_cells.h
@@ -43,7 +43,7 @@
 // There is also an image and an optional menu button.
 @interface BookmarkCell : UICollectionViewCell<BookmarkImageableView>
 
-@property(nonatomic, retain, readonly) UILabel* titleLabel;
+@property(nonatomic, strong, readonly) UILabel* titleLabel;
 
 + (NSString*)reuseIdentifier;
 
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_collection_cells.mm b/ios/chrome/browser/ui/bookmarks/bookmark_collection_cells.mm
index 38ea805..315ceedc 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_collection_cells.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_collection_cells.mm
@@ -7,8 +7,7 @@
 #import <QuartzCore/QuartzCore.h>
 
 #include "base/logging.h"
-#include "base/mac/objc_property_releaser.h"
-#include "base/mac/scoped_nsobject.h"
+
 #import "ios/chrome/browser/ui/bookmarks/bookmark_extended_button.h"
 #import "ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.h"
 #import "ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h"
@@ -22,38 +21,37 @@
 #import "ui/gfx/ios/NSString+CrStringDrawing.h"
 #include "url/gurl.h"
 
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
 namespace {
 const CGFloat kBookmarkItemCellDefaultImageSize = 40.0;
 const CGFloat kBookmarkFolderCellDefaultImageSize = 24.0;
 }  // namespace
 
-@interface BookmarkCell () {
- @protected
-  // Subclasses should set these in the constructor with the wanted values.
-  CGFloat _imageSize;
-
- @private
-  base::mac::ObjCPropertyReleaser _propertyReleaser_BookmarkCell;
-}
+@interface BookmarkCell ()
 // Redefined to be read-write.
-@property(nonatomic, retain) UILabel* titleLabel;
+@property(nonatomic, strong) UILabel* titleLabel;
 // Redefined to readwrite.
-@property(nonatomic, retain) UIImageView* imageView;
+@property(nonatomic, strong) UIImageView* imageView;
 // Label to show placeholder text when there is no image displayed.
-@property(nonatomic, retain) UILabel* placeholderLabel;
+@property(nonatomic, strong) UILabel* placeholderLabel;
 // When the cell is selected for editing, a cover is shown with a blue color.
 // Subclasses should insert new views below this view.
-@property(nonatomic, retain) UIView* highlightCover;
+@property(nonatomic, strong) UIView* highlightCover;
 // Lists the accessibility elements that are to be seen by UIAccessibility.
 @property(nonatomic, readonly) NSMutableArray* accessibilityElements;
 // Location of the last touch on the cell.
 @property(nonatomic, assign) CGPoint touchLocation;
 // The view doing the highlight animation. Only set while the cell is
 // highlighted.
-@property(nonatomic, retain) MDCInkView* touchFeedbackView;
-@property(nonatomic, retain) BookmarkExtendedButton* button;
+@property(nonatomic, strong) MDCInkView* touchFeedbackView;
+@property(nonatomic, strong) BookmarkExtendedButton* button;
 @property(nonatomic, assign) SEL buttonAction;
-@property(nonatomic, assign) id buttonTarget;
+@property(nonatomic, weak) id buttonTarget;
+// Side of a square image. Subclasses should set this to desired size.
+@property(nonatomic, assign) CGFloat imageSize;
 @end
 
 @implementation BookmarkCell
@@ -68,6 +66,7 @@
 @synthesize buttonAction = _buttonAction;
 @synthesize buttonTarget = _buttonTarget;
 @synthesize placeholderLabel = _placeholderLabel;
+@synthesize imageSize = _imageSize;
 
 + (NSString*)reuseIdentifier {
   NOTREACHED();
@@ -77,7 +76,6 @@
 - (instancetype)initWithFrame:(CGRect)frame {
   self = [super initWithFrame:frame];
   if (self) {
-    _propertyReleaser_BookmarkCell.Init(self, [BookmarkCell class]);
     self.exclusiveTouch = YES;
     self.backgroundColor = [UIColor whiteColor];
 
@@ -102,8 +100,7 @@
     _highlightCover.translatesAutoresizingMaskIntoConstraints = NO;
     [self.contentView addSubview:_highlightCover];
 
-    self.button = base::scoped_nsobject<BookmarkExtendedButton>(
-        [[BookmarkExtendedButton alloc] init]);
+    self.button = [[BookmarkExtendedButton alloc] init];
     self.button.contentMode = UIViewContentModeCenter;
     self.button.backgroundColor = [UIColor clearColor];
     [self.button addTarget:self
@@ -127,7 +124,7 @@
 }
 
 - (void)updateConstraints {
-  if (_imageSize) {
+  if (self.imageSize) {
     // Create constraints.
 
     // Align all the views on the same horizontal line.
@@ -152,10 +149,10 @@
           @"highlight" : self.highlightCover
         },
         @{
-          @"buttonSize" : [NSNumber numberWithFloat:32.0],
-          @"leadingImageMargin" : [NSNumber numberWithFloat:16.0],
-          @"leadingMargin" : [NSNumber numberWithFloat:64.0],
-          @"imageSize" : [NSNumber numberWithFloat:_imageSize],
+          @"buttonSize" :@32.0,
+          @"leadingImageMargin" : @16.0,
+          @"leadingMargin" : @64.0,
+          @"imageSize" : @(self.imageSize),
         },
         self.contentView);
     // clang-format on
@@ -247,8 +244,8 @@
 
   if (highlighted) {
     // Creates an ink feedback and animates it.
-    base::scoped_nsobject<MDCInkView> touchFeedbackView(
-        [[MDCInkView alloc] initWithFrame:self.bounds]);
+    MDCInkView* touchFeedbackView =
+        [[MDCInkView alloc] initWithFrame:self.bounds];
     [self addSubview:touchFeedbackView];
     self.touchFeedbackView = touchFeedbackView;
     [self.touchFeedbackView startTouchBeganAnimationAtPoint:self.touchLocation
@@ -272,9 +269,12 @@
 }
 
 - (void)buttonTapped:(id)target {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
   [self.buttonTarget performSelector:self.buttonAction
                           withObject:self
                           withObject:target];
+#pragma clang diagnostic pop
 }
 
 - (void)showButtonOfType:(bookmark_cell::ButtonType)buttonType
@@ -355,11 +355,6 @@
 
 #pragma mark - BookmarkItemCell
 
-@interface BookmarkItemCell () {
-  base::mac::ObjCPropertyReleaser _propertyReleaser_BookmarkItemCell;
-}
-@end
-
 @implementation BookmarkItemCell
 
 + (NSString*)reuseIdentifier {
@@ -373,15 +368,13 @@
 - (instancetype)initWithFrame:(CGRect)frame {
   self = [super initWithFrame:frame];
   if (self) {
-    _propertyReleaser_BookmarkItemCell.Init(self, [BookmarkItemCell class]);
-
     // Set the non-layout properties of the titles.
     UIFont* font = [MDCTypography subheadFont];
     self.titleLabel.font = font;
     self.titleLabel.backgroundColor = [UIColor clearColor];
     self.titleLabel.numberOfLines = 1;
 
-    _imageSize = kBookmarkItemCellDefaultImageSize;
+    self.imageSize = kBookmarkItemCellDefaultImageSize;
   }
   return self;
 }
@@ -406,13 +399,6 @@
 @end
 
 #pragma mark - BookmarkFolderCell
-
-@interface BookmarkFolderCell () {
-  base::mac::ObjCPropertyReleaser _propertyReleaser_BookmarkFolderCell;
-}
-
-@end
-
 @implementation BookmarkFolderCell
 
 + (NSString*)reuseIdentifier {
@@ -422,12 +408,10 @@
 - (instancetype)initWithFrame:(CGRect)frame {
   self = [super initWithFrame:frame];
   if (self) {
-    _propertyReleaser_BookmarkFolderCell.Init(self, [BookmarkFolderCell class]);
-
     self.imageView.image = [UIImage imageNamed:@"bookmark_gray_folder"];
     self.titleLabel.font = [MDCTypography subheadFont];
 
-    _imageSize = kBookmarkFolderCellDefaultImageSize;
+    self.imageSize = kBookmarkFolderCellDefaultImageSize;
   }
   return self;
 }
@@ -448,14 +432,13 @@
 
 #pragma mark - BookmarkHeaderView
 
-@interface BookmarkHeaderView () {
-  base::mac::ObjCPropertyReleaser _propertyReleaser_BookmarkHeaderView;
-}
-@property(nonatomic, retain) UILabel* titleLabel;
+@interface BookmarkHeaderView ()
+@property(nonatomic, strong) UILabel* titleLabel;
 @end
 
 @implementation BookmarkHeaderView
 @synthesize titleLabel = _titleLabel;
+
 + (NSString*)reuseIdentifier {
   return @"BookmarkHeaderView";
 }
@@ -467,9 +450,7 @@
 - (instancetype)initWithFrame:(CGRect)frame {
   self = [super initWithFrame:frame];
   if (self) {
-    _propertyReleaser_BookmarkHeaderView.Init(self, [BookmarkHeaderView class]);
-    base::scoped_nsobject<UILabel> titleLabel(
-        [[UILabel alloc] initWithFrame:CGRectZero]);
+    UILabel* titleLabel = [[UILabel alloc] initWithFrame:CGRectZero];
     self.titleLabel = titleLabel;
     UIFont* font = [MDCTypography body2Font];
     self.titleLabel.font = font;
@@ -507,11 +488,9 @@
 
 #pragma mark - BookmarkHeaderSeparatorView
 
-@interface BookmarkHeaderSeparatorView () {
-  base::mac::ObjCPropertyReleaser _propertyReleaser_BookmarkHeaderSeparatorView;
-}
+@interface BookmarkHeaderSeparatorView ()
 // The bottom separator line.
-@property(nonatomic, retain) UIView* lineView;
+@property(nonatomic, strong) UIView* lineView;
 @end
 
 @implementation BookmarkHeaderSeparatorView
@@ -529,8 +508,6 @@
 - (instancetype)initWithFrame:(CGRect)frame {
   self = [super initWithFrame:frame];
   if (self) {
-    _propertyReleaser_BookmarkHeaderSeparatorView.Init(
-        self, [BookmarkHeaderSeparatorView class]);
     _lineView = [[UIView alloc] init];
     _lineView.backgroundColor = bookmark_utils_ios::separatorColor();
     [self addSubview:_lineView];
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_collection_view.h b/ios/chrome/browser/ui/bookmarks/bookmark_collection_view.h
index 7f0d6323..6f3ed19 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_collection_view.h
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_collection_view.h
@@ -213,7 +213,7 @@
 #pragma mark - Commonly used properties
 
 @property(nonatomic, assign, readonly) bookmarks::BookmarkModel* bookmarkModel;
-@property(nonatomic, assign, readonly) id<UrlLoader> loader;
+@property(nonatomic, weak, readonly) id<UrlLoader> loader;
 @property(nonatomic, assign, readonly) ios::ChromeBrowserState* browserState;
 
 #pragma mark - Editing
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_collection_view.mm b/ios/chrome/browser/ui/bookmarks/bookmark_collection_view.mm
index e342f092..01654b98 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_collection_view.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_collection_view.mm
@@ -9,11 +9,8 @@
 #include <map>
 #include <memory>
 
-#include "base/ios/weak_nsobject.h"
 #include "base/mac/bind_objc_block.h"
 #include "base/mac/foundation_util.h"
-#include "base/mac/objc_property_releaser.h"
-#include "base/mac/scoped_nsobject.h"
 #include "base/strings/sys_string_conversions.h"
 #include "components/bookmarks/browser/bookmark_model.h"
 #include "components/bookmarks/browser/bookmark_model_observer.h"
@@ -34,6 +31,10 @@
 #include "skia/ext/skia_utils_ios.h"
 #include "ui/base/l10n/l10n_util_mac.h"
 
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
 using bookmarks::BookmarkNode;
 
 namespace {
@@ -62,8 +63,6 @@
   std::unique_ptr<bookmarks::BookmarkModelBridge> _modelBridge;
   ios::ChromeBrowserState* _browserState;
 
-  base::mac::ObjCPropertyReleaser _propertyReleaser_BookmarkCollectionView;
-
   // Map of favicon load tasks for each index path. Used to keep track of
   // pending favicon load operations so that they can be cancelled upon cell
   // reuse. Keys are (section, item) pairs of cell index paths.
@@ -75,16 +74,16 @@
 // Redefined to be readwrite.
 @property(nonatomic, assign) bookmarks::BookmarkModel* bookmarkModel;
 // Redefined to be readwrite.
-@property(nonatomic, retain) UICollectionView* collectionView;
+@property(nonatomic, strong) UICollectionView* collectionView;
 // Redefined to be readwrite.
 @property(nonatomic, assign) BOOL editing;
 // Detects a long press on a cell.
-@property(nonatomic, retain) UILongPressGestureRecognizer* longPressRecognizer;
+@property(nonatomic, strong) UILongPressGestureRecognizer* longPressRecognizer;
 // Background view of the collection view shown when there is no items.
-@property(nonatomic, retain)
+@property(nonatomic, strong)
     BookmarkCollectionViewBackground* emptyCollectionBackgroundView;
 // Shadow to display over the content.
-@property(nonatomic, retain) UIView* shadow;
+@property(nonatomic, strong) UIView* shadow;
 
 // Updates the editing state for the cell.
 - (void)updateEditingStateOfCell:(BookmarkCell*)cell
@@ -137,9 +136,6 @@
                                frame:(CGRect)frame {
   self = [super initWithFrame:frame];
   if (self) {
-    _propertyReleaser_BookmarkCollectionView.Init(
-        self, [BookmarkCollectionView class]);
-
     _browserState = browserState;
 
     // Set up connection to the BookmarkModel.
@@ -170,17 +166,16 @@
     [moi self];
   });
   _faviconTaskTracker.TryCancelAll();
-  [super dealloc];
 }
 
 - (void)setupViews {
   self.backgroundColor = bookmark_utils_ios::mainBackgroundColor();
-  base::scoped_nsobject<UICollectionViewFlowLayout> layout(
-      [[UICollectionViewFlowLayout alloc] init]);
+  UICollectionViewFlowLayout* layout =
+      [[UICollectionViewFlowLayout alloc] init];
 
-  base::scoped_nsobject<UICollectionView> collectionView(
+  UICollectionView* collectionView =
       [[UICollectionView alloc] initWithFrame:self.bounds
-                         collectionViewLayout:layout]);
+                         collectionViewLayout:layout];
   self.collectionView = collectionView;
   self.collectionView.backgroundColor = [UIColor clearColor];
   self.collectionView.autoresizingMask =
@@ -205,9 +200,8 @@
   [self addSubview:self.collectionView];
 
   // Set up the background view shown when the collection is empty.
-  base::scoped_nsobject<BookmarkCollectionViewBackground>
-      emptyCollectionBackgroundView(
-          [[BookmarkCollectionViewBackground alloc] initWithFrame:CGRectZero]);
+  BookmarkCollectionViewBackground* emptyCollectionBackgroundView =
+      [[BookmarkCollectionViewBackground alloc] initWithFrame:CGRectZero];
   self.emptyCollectionBackgroundView = emptyCollectionBackgroundView;
   self.emptyCollectionBackgroundView.autoresizingMask =
       UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
@@ -219,11 +213,9 @@
 
   [self updateShadow];
 
-  self.longPressRecognizer =
-      base::scoped_nsobject<UILongPressGestureRecognizer>(
-          [[UILongPressGestureRecognizer alloc]
-              initWithTarget:self
-                      action:@selector(longPress:)]);
+  self.longPressRecognizer = [[UILongPressGestureRecognizer alloc]
+      initWithTarget:self
+              action:@selector(longPress:)];
   self.longPressRecognizer.delegate = self;
   [self.collectionView addGestureRecognizer:self.longPressRecognizer];
 }
@@ -240,10 +232,9 @@
     self.shadow =
         bookmark_utils_ios::dropShadowWithWidth(CGRectGetWidth(self.bounds));
   } else {
-    self.shadow = [[[UIView alloc]
+    self.shadow = [[UIView alloc]
         initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.bounds),
-                                 1 / [[UIScreen mainScreen] scale])]
-        autorelease];
+                                 1 / [[UIScreen mainScreen] scale])];
     self.shadow.backgroundColor = [UIColor colorWithWhite:0.0 alpha:.12];
   }
 
@@ -486,12 +477,12 @@
   [self cancelLoadingFaviconAtIndexPath:indexPath];
 
   // Start loading a favicon.
-  base::WeakNSObject<BookmarkCollectionView> weakSelf(self);
+  __weak BookmarkCollectionView* weakSelf = self;
   const bookmarks::BookmarkNode* node = [self nodeAtIndexPath:indexPath];
   GURL blockURL(node->url());
   void (^faviconBlock)(const favicon_base::LargeIconResult&) = ^(
       const favicon_base::LargeIconResult& result) {
-    base::scoped_nsobject<BookmarkCollectionView> strongSelf([weakSelf retain]);
+    BookmarkCollectionView* strongSelf = weakSelf;
     if (!strongSelf)
       return;
     UIImage* favIcon = nil;
@@ -499,8 +490,7 @@
     UIColor* textColor = nil;
     NSString* fallbackText = nil;
     if (result.bitmap.is_valid()) {
-      scoped_refptr<base::RefCountedMemory> data =
-          result.bitmap.bitmap_data.get();
+      scoped_refptr<base::RefCountedMemory> data = result.bitmap.bitmap_data;
       favIcon = [UIImage imageWithData:[NSData dataWithBytes:data->front()
                                                       length:data->size()]];
     } else if (result.fallback_icon_style) {
@@ -527,7 +517,7 @@
   base::CancelableTaskTracker::TaskId taskId =
       IOSChromeLargeIconServiceFactory::GetForBrowserState(self.browserState)
           ->GetLargeIconOrFallbackStyle(node->url(), minSize, preferredSize,
-                                        base::BindBlock(faviconBlock),
+                                        base::BindBlockArc(faviconBlock),
                                         &_faviconTaskTracker);
   _faviconLoadTasks[IntegerPair(indexPath.section, indexPath.item)] = taskId;
 }
@@ -701,8 +691,7 @@
     UICollectionViewCell* cell =
         [self.collectionView cellForItemAtIndexPath:indexPath];
     if (!cell) {
-      cell = [[[BookmarkPromoCell alloc] initWithFrame:estimatedFrame]
-          autorelease];
+      cell = [[BookmarkPromoCell alloc] initWithFrame:estimatedFrame];
     }
     cell.frame = estimatedFrame;
     [cell layoutIfNeeded];
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_collection_view_background.mm b/ios/chrome/browser/ui/bookmarks/bookmark_collection_view_background.mm
index f897477..38461e5 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_collection_view_background.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_collection_view_background.mm
@@ -4,9 +4,12 @@
 
 #include "ios/chrome/browser/ui/bookmarks/bookmark_collection_view_background.h"
 
-#include "base/mac/objc_property_releaser.h"
 #import "ios/third_party/material_roboto_font_loader_ios/src/src/MaterialRobotoFontLoader.h"
 
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
 namespace {
 NSString* const kBookmarkGrayStar = @"bookmark_gray_star_large";
 const CGFloat kEmptyBookmarkTextSize = 16.0;
@@ -14,10 +17,7 @@
 const CGFloat kImageViewOffsetFromText = 5.0;
 }  // namespace
 
-@interface BookmarkCollectionViewBackground () {
-  base::mac::ObjCPropertyReleaser
-      _propertyReleaser_BookmarkBookmarkCollectionViewBackground;
-}
+@interface BookmarkCollectionViewBackground ()
 
 // Star image view shown on top of the label.
 @property(nonatomic, retain) UIImageView* emptyBookmarksImageView;
@@ -34,8 +34,6 @@
 - (instancetype)initWithFrame:(CGRect)frame {
   self = [super initWithFrame:frame];
   if (self) {
-    _propertyReleaser_BookmarkBookmarkCollectionViewBackground.Init(
-        self, [BookmarkCollectionViewBackground class]);
     _emptyBookmarksImageView = [self newBookmarkImageView];
     [self addSubview:_emptyBookmarksImageView];
     _emptyBookmarksLabel = [self newEmptyBookmarkLabel];
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_controller_factory.mm b/ios/chrome/browser/ui/bookmarks/bookmark_controller_factory.mm
index 9cb334c..4d003c3e8 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_controller_factory.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_controller_factory.mm
@@ -8,23 +8,26 @@
 #import "ios/chrome/browser/ui/bookmarks/bookmark_home_handset_view_controller.h"
 #import "ios/chrome/browser/ui/bookmarks/bookmark_home_tablet_ntp_controller.h"
 
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
 @implementation BookmarkControllerFactory
 
 - (BookmarkHomeViewController*)
 bookmarkControllerWithBrowserState:(ios::ChromeBrowserState*)browserState
                             loader:(id<UrlLoader>)loader {
-  return [[[BookmarkHomeHandsetViewController alloc]
-      initWithLoader:loader
-        browserState:browserState] autorelease];
+  return
+      [[BookmarkHomeHandsetViewController alloc] initWithLoader:loader
+                                                   browserState:browserState];
 }
 
 - (id<NewTabPagePanelProtocol>)
 bookmarkPanelControllerForBrowserState:(ios::ChromeBrowserState*)browserState
                                 loader:(id<UrlLoader>)loader
                             colorCache:(NSMutableDictionary*)cache {
-  return [[[BookmarkHomeTabletNTPController alloc] initWithLoader:loader
-                                                     browserState:browserState]
-      autorelease];
+  return [[BookmarkHomeTabletNTPController alloc] initWithLoader:loader
+                                                    browserState:browserState];
 }
 
 @end
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.h b/ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.h
index 5a53071a..081260af 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.h
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.h
@@ -43,7 +43,7 @@
 // changes underneath it.
 @interface BookmarkEditViewController : CollectionViewController
 
-@property(nonatomic, assign) id<BookmarkEditViewControllerDelegate> delegate;
+@property(nonatomic, weak) id<BookmarkEditViewControllerDelegate> delegate;
 
 // Designated initializer.
 // |bookmark|: mustn't be NULL at initialization time. It also mustn't be a
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.mm b/ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.mm
index 96a88858..f742137f 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.mm
@@ -9,13 +9,11 @@
 
 #include "base/auto_reset.h"
 #include "base/ios/block_types.h"
-#include "base/ios/weak_nsobject.h"
 #include "base/logging.h"
 #include "base/mac/bind_objc_block.h"
 #import "base/mac/foundation_util.h"
-#include "base/mac/objc_property_releaser.h"
+
 #include "base/mac/scoped_cftyperef.h"
-#include "base/mac/scoped_nsobject.h"
 #include "base/strings/sys_string_conversions.h"
 #include "components/bookmarks/browser/bookmark_model.h"
 #include "components/url_formatter/url_fixer.h"
@@ -45,6 +43,10 @@
 #include "ui/gfx/image/image.h"
 #include "url/gurl.h"
 
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
 using bookmarks::BookmarkModel;
 using bookmarks::BookmarkNode;
 
@@ -78,8 +80,6 @@
   BOOL _ignoresBookmarkModelChanges;
 
   std::unique_ptr<bookmarks::BookmarkModelBridge> _modelBridge;
-
-  base::mac::ObjCPropertyReleaser _propertyReleaser_BookmarkEditViewController;
 }
 
 // The bookmark this controller displays or edits.
@@ -97,20 +97,20 @@
 
 // The folder picker view controller.
 // Redefined to be readwrite.
-@property(nonatomic, retain) BookmarkFolderViewController* folderViewController;
+@property(nonatomic, strong) BookmarkFolderViewController* folderViewController;
 
 @property(nonatomic, assign) ios::ChromeBrowserState* browserState;
 
 // Cancel button item in navigation bar.
-@property(nonatomic, retain) UIBarButtonItem* cancelItem;
+@property(nonatomic, strong) UIBarButtonItem* cancelItem;
 
 // Done button item in navigation bar.
-@property(nonatomic, retain) UIBarButtonItem* doneItem;
+@property(nonatomic, strong) UIBarButtonItem* doneItem;
 
 // CollectionViewItem-s from the collection.
-@property(nonatomic, retain) BookmarkTextFieldItem* nameItem;
-@property(nonatomic, retain) BookmarkParentFolderItem* folderItem;
-@property(nonatomic, retain) BookmarkTextFieldItem* URLItem;
+@property(nonatomic, strong) BookmarkTextFieldItem* nameItem;
+@property(nonatomic, strong) BookmarkParentFolderItem* folderItem;
+@property(nonatomic, strong) BookmarkTextFieldItem* URLItem;
 
 // Reports the changes to the delegate, that has the responsibility to save the
 // bookmark.
@@ -168,8 +168,6 @@
   DCHECK(browserState);
   self = [super initWithStyle:CollectionViewControllerStyleAppBar];
   if (self) {
-    _propertyReleaser_BookmarkEditViewController.Init(
-        self, [BookmarkEditViewController class]);
     DCHECK(!bookmark->is_folder());
     DCHECK(!browserState->IsOffTheRecord());
     _bookmark = bookmark;
@@ -189,7 +187,6 @@
 
 - (void)dealloc {
   _folderViewController.delegate = nil;
-  [super dealloc];
 }
 
 #pragma mark View lifecycle
@@ -211,36 +208,34 @@
   self.navigationItem.leftBarButtonItem = cancelItem;
   self.cancelItem = cancelItem;
 
-  base::scoped_nsobject<UIBarButtonItem> doneItem([[UIBarButtonItem alloc]
+  UIBarButtonItem* doneItem = [[UIBarButtonItem alloc]
       initWithTitle:l10n_util::GetNSString(IDS_IOS_BOOKMARK_DONE_BUTTON)
               style:UIBarButtonItemStylePlain
              target:self
-             action:@selector(save)]);
-  doneItem.get().accessibilityIdentifier = @"Done";
+             action:@selector(save)];
+  doneItem.accessibilityIdentifier = @"Done";
   self.navigationItem.rightBarButtonItem = doneItem;
   self.doneItem = doneItem;
 
-  base::scoped_nsobject<BookmarksElevatedToolbar> buttonBar(
-      [[BookmarksElevatedToolbar alloc] init]);
-  base::scoped_nsobject<UIBarButtonItem> deleteItem([[UIBarButtonItem alloc]
+  BookmarksElevatedToolbar* buttonBar = [[BookmarksElevatedToolbar alloc] init];
+  UIBarButtonItem* deleteItem = [[UIBarButtonItem alloc]
       initWithTitle:l10n_util::GetNSString(IDS_IOS_BOOKMARK_DELETE)
               style:UIBarButtonItemStylePlain
              target:self
-             action:@selector(deleteBookmark)]);
-  deleteItem.get().accessibilityIdentifier = @"Delete_action";
+             action:@selector(deleteBookmark)];
+  deleteItem.accessibilityIdentifier = @"Delete_action";
   [deleteItem setTitleTextAttributes:@{
     NSForegroundColorAttributeName : [UIColor blackColor]
   }
                             forState:UIControlStateNormal];
-  [buttonBar.get().layer
-      addSublayer:[[[MDCShadowLayer alloc] init] autorelease]];
-  buttonBar.get().shadowElevation = MDCShadowElevationSearchBarResting;
-  buttonBar.get().backgroundColor = [UIColor whiteColor];
-  buttonBar.get().items = @[ deleteItem ];
+  [buttonBar.layer addSublayer:[[MDCShadowLayer alloc] init]];
+  buttonBar.shadowElevation = MDCShadowElevationSearchBarResting;
+  buttonBar.backgroundColor = [UIColor whiteColor];
+  buttonBar.items = @[ deleteItem ];
   [self.view addSubview:buttonBar];
 
   // Constraint |buttonBar| to be in bottom
-  buttonBar.get().translatesAutoresizingMaskIntoConstraints = NO;
+  buttonBar.translatesAutoresizingMaskIntoConstraints = NO;
   [self.view addConstraints:
                  [NSLayoutConstraint
                      constraintsWithVisualFormat:@"H:|[buttonBar]|"
@@ -348,8 +343,7 @@
 
   [model addSectionWithIdentifier:SectionIdentifierInfo];
 
-  self.nameItem =
-      [[[BookmarkTextFieldItem alloc] initWithType:ItemTypeName] autorelease];
+  self.nameItem = [[BookmarkTextFieldItem alloc] initWithType:ItemTypeName];
   self.nameItem.accessibilityIdentifier = @"Title Field";
   self.nameItem.placeholder =
       l10n_util::GetNSString(IDS_IOS_BOOKMARK_NAME_FIELD_HEADER);
@@ -357,13 +351,12 @@
   self.nameItem.delegate = self;
   [model addItem:self.nameItem toSectionWithIdentifier:SectionIdentifierInfo];
 
-  self.folderItem = [[[BookmarkParentFolderItem alloc]
-      initWithType:ItemTypeFolder] autorelease];
+  self.folderItem =
+      [[BookmarkParentFolderItem alloc] initWithType:ItemTypeFolder];
   self.folderItem.title = bookmark_utils_ios::TitleForBookmarkNode(self.folder);
   [model addItem:self.folderItem toSectionWithIdentifier:SectionIdentifierInfo];
 
-  self.URLItem =
-      [[[BookmarkTextFieldItem alloc] initWithType:ItemTypeURL] autorelease];
+  self.URLItem = [[BookmarkTextFieldItem alloc] initWithType:ItemTypeURL];
   self.URLItem.accessibilityIdentifier = @"URL Field";
   self.URLItem.placeholder =
       l10n_util::GetNSString(IDS_IOS_BOOKMARK_URL_FIELD_HEADER);
@@ -410,14 +403,14 @@
 
   std::set<const BookmarkNode*> editedNodes;
   editedNodes.insert(self.bookmark);
-  base::scoped_nsobject<BookmarkFolderViewController> folderViewController(
+  BookmarkFolderViewController* folderViewController =
       [[BookmarkFolderViewController alloc]
           initWithBookmarkModel:self.bookmarkModel
                allowsNewFolders:YES
                     editedNodes:editedNodes
                    allowsCancel:NO
-                 selectedFolder:self.folder]);
-  folderViewController.get().delegate = self;
+                 selectedFolder:self.folder];
+  folderViewController.delegate = self;
   self.folderViewController = folderViewController;
 
   [self.navigationController pushViewController:self.folderViewController
@@ -583,7 +576,7 @@
 #pragma mark - UIResponder
 
 - (NSArray*)keyCommands {
-  base::WeakNSObject<BookmarkEditViewController> weakSelf(self);
+  __weak BookmarkEditViewController* weakSelf = self;
   return @[ [UIKeyCommand cr_keyCommandWithInput:UIKeyInputEscape
                                    modifierFlags:Cr_UIKeyModifierNone
                                            title:nil
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_elevated_toolbar.mm b/ios/chrome/browser/ui/bookmarks/bookmark_elevated_toolbar.mm
index 0c2329a..4bef5ba 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_elevated_toolbar.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_elevated_toolbar.mm
@@ -4,27 +4,16 @@
 
 #import "ios/chrome/browser/ui/bookmarks/bookmark_elevated_toolbar.h"
 
-#include "base/mac/objc_property_releaser.h"
 #import "ios/third_party/material_components_ios/src/components/ShadowElevations/src/MaterialShadowElevations.h"
 #import "ios/third_party/material_components_ios/src/components/ShadowLayer/src/MaterialShadowLayer.h"
 
-@implementation BookmarksElevatedToolbar {
-  base::mac::ObjCPropertyReleaser _propertyReleaser_BookmarksElevatedToolbar;
-}
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
 
+@implementation BookmarksElevatedToolbar
 @synthesize shadowLayer = _shadowLayer;
 
-#pragma mark - Lifecycle
-
-- (instancetype)init {
-  self = [super init];
-  if (self) {
-    _propertyReleaser_BookmarksElevatedToolbar.Init(
-        self, [BookmarksElevatedToolbar class]);
-  }
-  return self;
-}
-
 #pragma mark - Properties
 
 - (MDCShadowLayer*)shadowLayer {
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_extended_button.mm b/ios/chrome/browser/ui/bookmarks/bookmark_extended_button.mm
index 092dab26..c691be9094 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_extended_button.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_extended_button.mm
@@ -6,6 +6,10 @@
 
 #include "base/logging.h"
 
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
 namespace {
 // Apple's guidelines indicate that buttons should have a minimum touch area of
 // 44pt x 44pt.
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_folder_collection_view.h b/ios/chrome/browser/ui/bookmarks/bookmark_folder_collection_view.h
index 7f0dff2..408b0bf 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_folder_collection_view.h
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_folder_collection_view.h
@@ -31,7 +31,7 @@
 // Called when something outside the view causes the promo state to change.
 - (void)promoStateChangedAnimated:(BOOL)animate;
 
-@property(nonatomic, assign) id<BookmarkFolderCollectionViewDelegate> delegate;
+@property(nonatomic, weak) id<BookmarkFolderCollectionViewDelegate> delegate;
 @property(nonatomic, assign, readonly) const bookmarks::BookmarkNode* folder;
 
 @end
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_folder_collection_view.mm b/ios/chrome/browser/ui/bookmarks/bookmark_folder_collection_view.mm
index ffcbd4f..4b2a16a 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_folder_collection_view.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_folder_collection_view.mm
@@ -5,7 +5,6 @@
 #import "ios/chrome/browser/ui/bookmarks/bookmark_folder_collection_view.h"
 
 #include "base/logging.h"
-#include "base/mac/objc_property_releaser.h"
 #include "base/strings/sys_string_conversions.h"
 #include "components/bookmarks/browser/bookmark_model.h"
 #include "ios/chrome/browser/bookmarks/bookmarks_utils.h"
@@ -14,11 +13,13 @@
 #import "ios/chrome/browser/ui/bookmarks/bookmark_promo_cell.h"
 #import "ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h"
 
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
 using bookmarks::BookmarkNode;
 
 @interface BookmarkFolderCollectionView ()<BookmarkPromoCellDelegate> {
-  base::mac::ObjCPropertyReleaser
-      _propertyReleaser_BookmarkFolderCollectionView;
   // A vector of folders to display in the collection view.
   std::vector<const BookmarkNode*> _subFolders;
   // A vector of bookmark urls to display in the collection view.
@@ -36,7 +37,7 @@
 @property(nonatomic, readonly, assign) NSInteger sectionCount;
 
 // Keep a reference to the promo cell to deregister as delegate.
-@property(nonatomic, retain) BookmarkPromoCell* promoCell;
+@property(nonatomic, strong) BookmarkPromoCell* promoCell;
 
 @end
 
@@ -49,9 +50,6 @@
                                frame:(CGRect)frame {
   self = [super initWithBrowserState:browserState frame:frame];
   if (self) {
-    _propertyReleaser_BookmarkFolderCollectionView.Init(
-        self, [BookmarkFolderCollectionView class]);
-
     [self updateCollectionView];
   }
   return self;
@@ -59,7 +57,6 @@
 
 - (void)dealloc {
   _promoCell.delegate = nil;
-  [super dealloc];
 }
 
 - (void)setDelegate:(id<BookmarkFolderCollectionViewDelegate>)delegate {
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_folder_editor_view_controller.h b/ios/chrome/browser/ui/bookmarks/bookmark_folder_editor_view_controller.h
index f8eb144..737f1b1 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_folder_editor_view_controller.h
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_folder_editor_view_controller.h
@@ -39,7 +39,7 @@
 // bookmark model can affect this controller's state.
 @interface BookmarkFolderEditorViewController : CollectionViewController
 
-@property(nonatomic, assign) id<BookmarkFolderEditorViewControllerDelegate>
+@property(nonatomic, weak) id<BookmarkFolderEditorViewControllerDelegate>
     delegate;
 
 // Designated factory methods.
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_folder_editor_view_controller.mm b/ios/chrome/browser/ui/bookmarks/bookmark_folder_editor_view_controller.mm
index 6f6de34..19eb7573 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_folder_editor_view_controller.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_folder_editor_view_controller.mm
@@ -8,11 +8,9 @@
 
 #include "base/auto_reset.h"
 #include "base/i18n/rtl.h"
-#import "base/ios/weak_nsobject.h"
 #include "base/logging.h"
 #include "base/mac/foundation_util.h"
-#include "base/mac/objc_property_releaser.h"
-#include "base/mac/scoped_nsobject.h"
+
 #include "base/strings/sys_string_conversions.h"
 #include "components/bookmarks/browser/bookmark_model.h"
 #include "components/bookmarks/browser/bookmark_node.h"
@@ -35,6 +33,10 @@
 #import "ios/third_party/material_components_ios/src/components/Typography/src/MaterialTypography.h"
 #include "ui/base/l10n/l10n_util.h"
 
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
 using bookmarks::BookmarkNode;
 
 namespace {
@@ -55,8 +57,7 @@
     BookmarkModelBridgeObserver,
     BookmarkTextFieldItemDelegate> {
   std::unique_ptr<bookmarks::BookmarkModelBridge> _modelBridge;
-  base::mac::ObjCPropertyReleaser
-      _propertyReleaser_BookmarkFolderEditorViewController;
+
   // Flag to ignore bookmark model Move notifications when the move is performed
   // by this class.
   BOOL _ignoresOwnMove;
@@ -65,14 +66,14 @@
 @property(nonatomic, assign) bookmarks::BookmarkModel* bookmarkModel;
 @property(nonatomic, assign) ios::ChromeBrowserState* browserState;
 @property(nonatomic, assign) const BookmarkNode* folder;
-@property(nonatomic, retain) BookmarkFolderViewController* folderViewController;
+@property(nonatomic, strong) BookmarkFolderViewController* folderViewController;
 @property(nonatomic, assign) const BookmarkNode* parentFolder;
-@property(nonatomic, assign) UIBarButtonItem* doneItem;
-@property(nonatomic, retain) BookmarkTextFieldItem* titleItem;
-@property(nonatomic, retain) BookmarkParentFolderItem* parentFolderItem;
+@property(nonatomic, weak) UIBarButtonItem* doneItem;
+@property(nonatomic, strong) BookmarkTextFieldItem* titleItem;
+@property(nonatomic, strong) BookmarkParentFolderItem* parentFolderItem;
 // Bottom toolbar with DELETE button that only appears when the edited folder
 // allows deletion.
-@property(nonatomic, assign) BookmarksElevatedToolbar* toolbar;
+@property(nonatomic, weak) BookmarksElevatedToolbar* toolbar;
 
 // |bookmarkModel| must not be NULL and must be loaded.
 - (instancetype)initWithBookmarkModel:(bookmarks::BookmarkModel*)bookmarkModel
@@ -113,12 +114,12 @@
 + (instancetype)
 folderCreatorWithBookmarkModel:(bookmarks::BookmarkModel*)bookmarkModel
                   parentFolder:(const BookmarkNode*)parentFolder {
-  base::scoped_nsobject<BookmarkFolderEditorViewController> folderCreator(
-      [[self alloc] initWithBookmarkModel:bookmarkModel]);
-  folderCreator.get().parentFolder = parentFolder;
-  folderCreator.get().folder = NULL;
-  folderCreator.get().editingExistingFolder = NO;
-  return folderCreator.autorelease();
+  BookmarkFolderEditorViewController* folderCreator =
+      [[self alloc] initWithBookmarkModel:bookmarkModel];
+  folderCreator.parentFolder = parentFolder;
+  folderCreator.folder = NULL;
+  folderCreator.editingExistingFolder = NO;
+  return folderCreator;
 }
 
 + (instancetype)
@@ -128,13 +129,13 @@
   DCHECK(folder);
   DCHECK(!bookmarkModel->is_permanent_node(folder));
   DCHECK(browserState);
-  base::scoped_nsobject<BookmarkFolderEditorViewController> folderEditor(
-      [[self alloc] initWithBookmarkModel:bookmarkModel]);
-  folderEditor.get().parentFolder = folder->parent();
-  folderEditor.get().folder = folder;
-  folderEditor.get().browserState = browserState;
-  folderEditor.get().editingExistingFolder = YES;
-  return folderEditor.autorelease();
+  BookmarkFolderEditorViewController* folderEditor =
+      [[self alloc] initWithBookmarkModel:bookmarkModel];
+  folderEditor.parentFolder = folder->parent();
+  folderEditor.folder = folder;
+  folderEditor.browserState = browserState;
+  folderEditor.editingExistingFolder = YES;
+  return folderEditor;
 }
 
 #pragma mark - Initialization
@@ -144,8 +145,6 @@
   DCHECK(bookmarkModel->loaded());
   self = [super initWithStyle:CollectionViewControllerStyleAppBar];
   if (self) {
-    _propertyReleaser_BookmarkFolderEditorViewController.Init(
-        self, [BookmarkFolderEditorViewController class]);
     _bookmarkModel = bookmarkModel;
 
     // Set up the bookmark model oberver.
@@ -163,7 +162,6 @@
 - (void)dealloc {
   _titleItem.delegate = nil;
   _folderViewController.delegate = nil;
-  [super dealloc];
 }
 
 #pragma mark - UIViewController
@@ -173,13 +171,13 @@
   self.collectionView.backgroundColor = [UIColor whiteColor];
 
   // Add Done button.
-  base::scoped_nsobject<UIBarButtonItem> doneItem([[UIBarButtonItem alloc]
+  UIBarButtonItem* doneItem = [[UIBarButtonItem alloc]
       initWithTitle:l10n_util::GetNSString(
                         IDS_IOS_BOOKMARK_EDIT_MODE_EXIT_MOBILE)
               style:UIBarButtonItemStylePlain
              target:self
-             action:@selector(saveFolder)]);
-  doneItem.get().accessibilityIdentifier = @"Save";
+             action:@selector(saveFolder)];
+  doneItem.accessibilityIdentifier = @"Save";
   self.navigationItem.rightBarButtonItem = doneItem;
   self.doneItem = doneItem;
 
@@ -273,14 +271,14 @@
   std::set<const BookmarkNode*> editedNodes;
   if (self.folder)
     editedNodes.insert(self.folder);
-  base::scoped_nsobject<BookmarkFolderViewController> folderViewController(
+  BookmarkFolderViewController* folderViewController =
       [[BookmarkFolderViewController alloc]
           initWithBookmarkModel:self.bookmarkModel
                allowsNewFolders:NO
                     editedNodes:editedNodes
                    allowsCancel:NO
-                 selectedFolder:self.parentFolder]);
-  folderViewController.get().delegate = self;
+                 selectedFolder:self.parentFolder];
+  folderViewController.delegate = self;
   self.folderViewController = folderViewController;
 
   [self.navigationController pushViewController:folderViewController
@@ -442,23 +440,23 @@
 
   [self.collectionViewModel addSectionWithIdentifier:SectionIdentifierInfo];
 
-  base::scoped_nsobject<BookmarkTextFieldItem> titleItem(
-      [[BookmarkTextFieldItem alloc] initWithType:ItemTypeFolderTitle]);
-  titleItem.get().text =
+  BookmarkTextFieldItem* titleItem =
+      [[BookmarkTextFieldItem alloc] initWithType:ItemTypeFolderTitle];
+  titleItem.text =
       (self.folder)
           ? bookmark_utils_ios::TitleForBookmarkNode(self.folder)
           : l10n_util::GetNSString(IDS_IOS_BOOKMARK_NEW_GROUP_DEFAULT_NAME);
-  titleItem.get().placeholder =
+  titleItem.placeholder =
       l10n_util::GetNSString(IDS_IOS_BOOKMARK_NEW_EDITOR_NAME_LABEL);
-  titleItem.get().accessibilityIdentifier = @"Title";
+  titleItem.accessibilityIdentifier = @"Title";
   [self.collectionViewModel addItem:titleItem
             toSectionWithIdentifier:SectionIdentifierInfo];
-  titleItem.get().delegate = self;
+  titleItem.delegate = self;
   self.titleItem = titleItem;
 
-  base::scoped_nsobject<BookmarkParentFolderItem> parentFolderItem(
-      [[BookmarkParentFolderItem alloc] initWithType:ItemTypeParentFolder]);
-  parentFolderItem.get().title =
+  BookmarkParentFolderItem* parentFolderItem =
+      [[BookmarkParentFolderItem alloc] initWithType:ItemTypeParentFolder];
+  parentFolderItem.title =
       bookmark_utils_ios::TitleForBookmarkNode(self.parentFolder);
   [self.collectionViewModel addItem:parentFolderItem
             toSectionWithIdentifier:SectionIdentifierInfo];
@@ -467,26 +465,24 @@
 
 - (void)addToolbar {
   // Add bottom toolbar with Delete button.
-  base::scoped_nsobject<BookmarksElevatedToolbar> buttonBar(
-      [[BookmarksElevatedToolbar alloc] init]);
-  base::scoped_nsobject<UIBarButtonItem> deleteItem([[UIBarButtonItem alloc]
+  BookmarksElevatedToolbar* buttonBar = [[BookmarksElevatedToolbar alloc] init];
+  UIBarButtonItem* deleteItem = [[UIBarButtonItem alloc]
       initWithTitle:l10n_util::GetNSString(IDS_IOS_BOOKMARK_GROUP_DELETE)
               style:UIBarButtonItemStylePlain
              target:self
-             action:@selector(deleteFolder)]);
-  deleteItem.get().accessibilityIdentifier = @"Delete Folder";
+             action:@selector(deleteFolder)];
+  deleteItem.accessibilityIdentifier = @"Delete Folder";
   [deleteItem setTitleTextAttributes:@{
     NSForegroundColorAttributeName : [UIColor blackColor]
   }
                             forState:UIControlStateNormal];
-  [buttonBar.get().layer
-      addSublayer:[[[MDCShadowLayer alloc] init] autorelease]];
-  buttonBar.get().shadowElevation = MDCShadowElevationSearchBarResting;
-  buttonBar.get().items = @[ deleteItem ];
+  [buttonBar.layer addSublayer:[[MDCShadowLayer alloc] init]];
+  buttonBar.shadowElevation = MDCShadowElevationSearchBarResting;
+  buttonBar.items = @[ deleteItem ];
   [self.view addSubview:buttonBar];
 
   // Constraint |buttonBar| to be in bottom.
-  buttonBar.get().translatesAutoresizingMaskIntoConstraints = NO;
+  buttonBar.translatesAutoresizingMaskIntoConstraints = NO;
   [self.view addConstraints:
                  [NSLayoutConstraint
                      constraintsWithVisualFormat:@"H:|[buttonBar]|"
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_folder_table_view_cell.mm b/ios/chrome/browser/ui/bookmarks/bookmark_folder_table_view_cell.mm
index 000130ab..a21b042 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_folder_table_view_cell.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_folder_table_view_cell.mm
@@ -4,13 +4,16 @@
 
 #import "ios/chrome/browser/ui/bookmarks/bookmark_folder_table_view_cell.h"
 
-#include "base/mac/scoped_nsobject.h"
 #import "ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h"
 #import "ios/chrome/browser/ui/rtl_geometry.h"
 #include "ios/chrome/grit/ios_strings.h"
 #import "ios/third_party/material_components_ios/src/components/Typography/src/MaterialTypography.h"
 #include "ui/base/l10n/l10n_util_mac.h"
 
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
 namespace {
 // The amount in points by which to offset horizontally the text label.
 const CGFloat kTitleLabelLeadingOffset = 18.0;
@@ -35,26 +38,24 @@
 }
 
 + (instancetype)folderCell {
-  base::scoped_nsobject<BookmarkFolderTableViewCell> folderCell(
+  BookmarkFolderTableViewCell* folderCell =
       [[[self class] alloc] initWithStyle:UITableViewCellStyleDefault
-                          reuseIdentifier:[self folderCellReuseIdentifier]]);
-  folderCell.get().indentationWidth = kFolderCellIndentationWidth;
-  folderCell.get().imageView.image =
-      [UIImage imageNamed:@"bookmark_gray_folder"];
-  return folderCell.autorelease();
+                          reuseIdentifier:[self folderCellReuseIdentifier]];
+  folderCell.indentationWidth = kFolderCellIndentationWidth;
+  folderCell.imageView.image = [UIImage imageNamed:@"bookmark_gray_folder"];
+  return folderCell;
 }
 
 + (instancetype)folderCreationCell {
-  base::scoped_nsobject<BookmarkFolderTableViewCell> newFolderCell(
-      [[[self class] alloc]
-            initWithStyle:UITableViewCellStyleDefault
-          reuseIdentifier:[self folderCreationCellReuseIdentifier]]);
-  newFolderCell.get().textLabel.text =
+  BookmarkFolderTableViewCell* newFolderCell = [[[self class] alloc]
+        initWithStyle:UITableViewCellStyleDefault
+      reuseIdentifier:[self folderCreationCellReuseIdentifier]];
+  newFolderCell.textLabel.text =
       l10n_util::GetNSString(IDS_IOS_BOOKMARK_CREATE_GROUP);
-  newFolderCell.get().imageView.image =
+  newFolderCell.imageView.image =
       [UIImage imageNamed:@"bookmark_gray_new_folder"];
-  newFolderCell.get().accessibilityIdentifier = @"Create New Folder";
-  return newFolderCell.autorelease();
+  newFolderCell.accessibilityIdentifier = @"Create New Folder";
+  return newFolderCell;
 }
 
 - (instancetype)initWithStyle:(UITableViewCellStyle)style
@@ -74,10 +75,10 @@
 - (void)setChecked:(BOOL)checked {
   if (checked != _checked) {
     _checked = checked;
-    base::scoped_nsobject<UIImageView> checkImageView(
+    UIImageView* checkImageView =
         checked ? [[UIImageView alloc]
                       initWithImage:[UIImage imageNamed:@"bookmark_blue_check"]]
-                : nil);
+                : nil;
     self.accessoryView = checkImageView;
   }
 }
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_folder_view_controller.h b/ios/chrome/browser/ui/bookmarks/bookmark_folder_view_controller.h
index d2deeaa..4236122 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_folder_view_controller.h
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_folder_view_controller.h
@@ -31,7 +31,7 @@
 // The bookmark model is assumed to be loaded, thus also not to be NULL.
 @interface BookmarkFolderViewController : UIViewController
 
-@property(nonatomic, assign) id<BookmarkFolderViewControllerDelegate> delegate;
+@property(nonatomic, weak) id<BookmarkFolderViewControllerDelegate> delegate;
 
 // The current nodes (bookmarks or folders) that are considered for a move.
 @property(nonatomic, assign, readonly)
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_folder_view_controller.mm b/ios/chrome/browser/ui/bookmarks/bookmark_folder_view_controller.mm
index da55fb7..e12d250b 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_folder_view_controller.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_folder_view_controller.mm
@@ -7,10 +7,7 @@
 #include <memory>
 #include <vector>
 
-#import "base/ios/weak_nsobject.h"
 #include "base/logging.h"
-#include "base/mac/objc_property_releaser.h"
-#include "base/mac/scoped_nsobject.h"
 #include "base/strings/sys_string_conversions.h"
 #include "components/bookmarks/browser/bookmark_model.h"
 #import "ios/chrome/browser/ui/bookmarks/bookmark_folder_editor_view_controller.h"
@@ -24,6 +21,10 @@
 #import "ios/third_party/material_components_ios/src/components/AppBar/src/MaterialAppBar.h"
 #include "ui/base/l10n/l10n_util_mac.h"
 
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
 using bookmarks::BookmarkNode;
 
 namespace {
@@ -54,9 +55,7 @@
   std::set<const BookmarkNode*> _editedNodes;
   std::vector<const BookmarkNode*> _folders;
   std::unique_ptr<bookmarks::BookmarkModelBridge> _modelBridge;
-  base::scoped_nsobject<MDCAppBar> _appBar;
-  base::mac::ObjCPropertyReleaser
-      _propertyReleaser_BookmarkFolderViewController;
+  MDCAppBar* _appBar;
 }
 
 // Should the controller setup Cancel and Done buttons instead of a back button.
@@ -72,7 +71,7 @@
 @property(nonatomic, readonly) const BookmarkNode* selectedFolder;
 
 // The view controller to present when creating a new folder.
-@property(nonatomic, retain)
+@property(nonatomic, strong)
     BookmarkFolderEditorViewController* folderAddController;
 
 // A linear list of folders.
@@ -80,7 +79,7 @@
     const std::vector<const BookmarkNode*>& folders;
 
 // The table view that displays the options and folders.
-@property(nonatomic, retain) UITableView* tableView;
+@property(nonatomic, strong) UITableView* tableView;
 
 // Returns the cell for the default section and the given |row|.
 - (BookmarkFolderTableViewCell*)defaultSectionCellForRow:(NSInteger)row;
@@ -126,8 +125,6 @@
   DCHECK(selectedFolder == NULL || selectedFolder->is_folder());
   self = [super initWithNibName:nil bundle:nil];
   if (self) {
-    _propertyReleaser_BookmarkFolderViewController.Init(
-        self, [BookmarkFolderViewController class]);
     _allowsCancel = allowsCancel;
     _allowsNewFolders = allowsNewFolders;
     _bookmarkModel = bookmarkModel;
@@ -138,7 +135,7 @@
     _modelBridge.reset(
         new bookmarks::BookmarkModelBridge(self, _bookmarkModel));
 
-    _appBar.reset([[MDCAppBar alloc] init]);
+    _appBar = [[MDCAppBar alloc] init];
     [self addChildViewController:[_appBar headerViewController]];
   }
   return self;
@@ -155,7 +152,6 @@
   _tableView.dataSource = nil;
   _tableView.delegate = nil;
   _folderAddController.delegate = nil;
-  [super dealloc];
 }
 
 - (UIStatusBarStyle)preferredStatusBarStyle {
@@ -174,13 +170,13 @@
 
   self.title = l10n_util::GetNSString(IDS_IOS_BOOKMARK_CHOOSE_GROUP_BUTTON);
 
-  base::scoped_nsobject<UIBarButtonItem> doneItem([[UIBarButtonItem alloc]
+  UIBarButtonItem* doneItem = [[UIBarButtonItem alloc]
       initWithTitle:l10n_util::GetNSString(
                         IDS_IOS_BOOKMARK_EDIT_MODE_EXIT_MOBILE)
               style:UIBarButtonItemStylePlain
              target:self
-             action:@selector(done:)]);
-  doneItem.get().accessibilityIdentifier = @"Done";
+             action:@selector(done:)];
+  doneItem.accessibilityIdentifier = @"Done";
   self.navigationItem.rightBarButtonItem = doneItem;
 
   if (self.allowsCancel) {
@@ -204,14 +200,14 @@
   }
 
   // The table view.
-  base::scoped_nsobject<UITableView> tableView([[UITableView alloc]
-      initWithFrame:self.view.bounds
-              style:UITableViewStylePlain]);
-  tableView.get().dataSource = self;
-  tableView.get().delegate = self;
-  tableView.get().autoresizingMask =
+  UITableView* tableView =
+      [[UITableView alloc] initWithFrame:self.view.bounds
+                                   style:UITableViewStylePlain];
+  tableView.dataSource = self;
+  tableView.delegate = self;
+  tableView.autoresizingMask =
       UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
-  tableView.get().separatorStyle = UITableViewCellSeparatorStyleNone;
+  tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
   [self.view addSubview:tableView];
   [self.view sendSubviewToBack:tableView];
   self.tableView = tableView;
@@ -337,18 +333,16 @@
   CGRect headerViewFrame =
       CGRectMake(0, 0, CGRectGetWidth(tableView.frame),
                  [self tableView:tableView heightForHeaderInSection:section]);
-  UIView* headerView =
-      [[[UIView alloc] initWithFrame:headerViewFrame] autorelease];
+  UIView* headerView = [[UIView alloc] initWithFrame:headerViewFrame];
   if (section == BookmarkFolderSectionFolders &&
       [self shouldShowDefaultSection]) {
     CGRect separatorFrame =
         CGRectMake(0, 0, CGRectGetWidth(headerView.bounds),
                    1.0 / [[UIScreen mainScreen] scale]);  // 1-pixel divider.
-    base::scoped_nsobject<UIView> separator(
-        [[UIView alloc] initWithFrame:separatorFrame]);
-    separator.get().autoresizingMask = UIViewAutoresizingFlexibleBottomMargin |
-                                       UIViewAutoresizingFlexibleWidth;
-    separator.get().backgroundColor = bookmark_utils_ios::separatorColor();
+    UIView* separator = [[UIView alloc] initWithFrame:separatorFrame];
+    separator.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin |
+                                 UIViewAutoresizingFlexibleWidth;
+    separator.backgroundColor = bookmark_utils_ios::separatorColor();
     [headerView addSubview:separator];
   }
   return headerView;
@@ -369,7 +363,7 @@
 
 - (UIView*)tableView:(UITableView*)tableView
     viewForFooterInSection:(NSInteger)section {
-  return [[[UIView alloc] init] autorelease];
+  return [[UIView alloc] init];
 }
 
 - (void)tableView:(UITableView*)tableView
@@ -538,16 +532,15 @@
 
 - (void)delayedNotifyDelegateOfSelection {
   self.view.userInteractionEnabled = NO;
-  base::WeakNSObject<BookmarkFolderViewController> weakSelf(self);
+  __weak BookmarkFolderViewController* weakSelf = self;
   dispatch_after(
       dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)),
       dispatch_get_main_queue(), ^{
-        base::scoped_nsobject<BookmarkFolderViewController> strongSelf(
-            [weakSelf retain]);
+        BookmarkFolderViewController* strongSelf = weakSelf;
         // Early return if the controller has been deallocated.
         if (!strongSelf)
           return;
-        strongSelf.get().view.userInteractionEnabled = YES;
+        strongSelf.view.userInteractionEnabled = YES;
         [strongSelf done:nil];
       });
 }
diff --git a/ios/chrome/browser/ui/settings/BUILD.gn b/ios/chrome/browser/ui/settings/BUILD.gn
index ea7a7b21..e7d6d7d 100644
--- a/ios/chrome/browser/ui/settings/BUILD.gn
+++ b/ios/chrome/browser/ui/settings/BUILD.gn
@@ -157,6 +157,7 @@
     "//ios/chrome/browser/ui",
     "//ios/chrome/browser/ui/alert_coordinator",
     "//ios/chrome/browser/ui/authentication",
+    "//ios/chrome/browser/ui/authentication:authentication_arc",
     "//ios/chrome/browser/ui/autofill/cells",
     "//ios/chrome/browser/ui/collection_view",
     "//ios/chrome/browser/ui/colors",
diff --git a/ios/chrome/browser/ui/settings/accounts_collection_view_controller.mm b/ios/chrome/browser/ui/settings/accounts_collection_view_controller.mm
index 0d97812..7f4629620 100644
--- a/ios/chrome/browser/ui/settings/accounts_collection_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/accounts_collection_view_controller.mm
@@ -28,6 +28,8 @@
 #include "ios/chrome/browser/sync/sync_setup_service.h"
 #include "ios/chrome/browser/sync/sync_setup_service_factory.h"
 #import "ios/chrome/browser/ui/alert_coordinator/alert_coordinator.h"
+#import "ios/chrome/browser/ui/authentication/account_control_item.h"
+#import "ios/chrome/browser/ui/authentication/resized_avatar_cache.h"
 #import "ios/chrome/browser/ui/authentication/signin_interaction_controller.h"
 #import "ios/chrome/browser/ui/collection_view/cells/MDCCollectionViewCell+Chrome.h"
 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_account_item.h"
@@ -39,10 +41,8 @@
 #include "ios/chrome/browser/ui/commands/ios_command_ids.h"
 #import "ios/chrome/browser/ui/commands/open_url_command.h"
 #import "ios/chrome/browser/ui/icons/chrome_icon.h"
-#import "ios/chrome/browser/ui/settings/cells/account_control_item.h"
 #import "ios/chrome/browser/ui/settings/settings_navigation_controller.h"
 #import "ios/chrome/browser/ui/settings/sync_settings_collection_view_controller.h"
-#import "ios/chrome/browser/ui/settings/utils/resized_avatar_cache.h"
 #import "ios/chrome/browser/ui/sync/sync_util.h"
 #include "ios/chrome/grit/ios_chromium_strings.h"
 #include "ios/chrome/grit/ios_strings.h"
diff --git a/ios/chrome/browser/ui/settings/cells/BUILD.gn b/ios/chrome/browser/ui/settings/cells/BUILD.gn
index f4c11e10..fdfc8c8 100644
--- a/ios/chrome/browser/ui/settings/cells/BUILD.gn
+++ b/ios/chrome/browser/ui/settings/cells/BUILD.gn
@@ -4,8 +4,6 @@
 
 source_set("cells") {
   sources = [
-    "account_control_item.h",
-    "account_control_item.mm",
     "account_signin_item.h",
     "account_signin_item.mm",
     "autofill_data_item.h",
@@ -45,7 +43,6 @@
     "//ios/chrome/browser/ui",
     "//ios/chrome/browser/ui/collection_view/cells",
     "//ios/chrome/browser/ui/colors",
-    "//ios/third_party/material_components_ios",
     "//ios/third_party/material_roboto_font_loader_ios",
     "//ui/base",
   ]
@@ -56,7 +53,6 @@
 source_set("unit_tests") {
   testonly = true
   sources = [
-    "account_control_item_unittest.mm",
     "account_signin_item_unittest.mm",
     "autofill_data_item_unittest.mm",
     "autofill_edit_item_unittest.mm",
@@ -80,8 +76,6 @@
     "//ios/chrome/app/strings",
     "//ios/chrome/browser/ui/collection_view/cells",
     "//ios/chrome/browser/ui/collection_view/cells:test_support",
-    "//ios/chrome/browser/ui/colors",
-    "//ios/third_party/material_components_ios",
     "//testing/gtest",
     "//ui/base",
   ]
diff --git a/ios/chrome/browser/ui/settings/material_cell_catalog_view_controller.mm b/ios/chrome/browser/ui/settings/material_cell_catalog_view_controller.mm
index 62af0ac..8448f2c 100644
--- a/ios/chrome/browser/ui/settings/material_cell_catalog_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/material_cell_catalog_view_controller.mm
@@ -13,6 +13,7 @@
 #import "ios/chrome/browser/payments/cells/autofill_profile_item.h"
 #import "ios/chrome/browser/payments/cells/payments_text_item.h"
 #import "ios/chrome/browser/payments/cells/price_item.h"
+#import "ios/chrome/browser/ui/authentication/account_control_item.h"
 #import "ios/chrome/browser/ui/autofill/cells/cvc_item.h"
 #import "ios/chrome/browser/ui/autofill/cells/status_item.h"
 #import "ios/chrome/browser/ui/autofill/cells/storage_switch_item.h"
@@ -24,7 +25,6 @@
 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_text_item.h"
 #import "ios/chrome/browser/ui/collection_view/collection_view_model.h"
 #import "ios/chrome/browser/ui/icons/chrome_icon.h"
-#import "ios/chrome/browser/ui/settings/cells/account_control_item.h"
 #import "ios/chrome/browser/ui/settings/cells/account_signin_item.h"
 #import "ios/chrome/browser/ui/settings/cells/autofill_data_item.h"
 #import "ios/chrome/browser/ui/settings/cells/autofill_edit_item.h"
diff --git a/ios/chrome/browser/ui/settings/sync_settings_collection_view_controller.mm b/ios/chrome/browser/ui/settings/sync_settings_collection_view_controller.mm
index 9e35a430..84bdcca 100644
--- a/ios/chrome/browser/ui/settings/sync_settings_collection_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/sync_settings_collection_view_controller.mm
@@ -28,6 +28,7 @@
 #include "ios/chrome/browser/sync/sync_setup_service.h"
 #include "ios/chrome/browser/sync/sync_setup_service_factory.h"
 #import "ios/chrome/browser/ui/authentication/authentication_flow.h"
+#import "ios/chrome/browser/ui/authentication/resized_avatar_cache.h"
 #import "ios/chrome/browser/ui/collection_view/cells/MDCCollectionViewCell+Chrome.h"
 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_account_item.h"
 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_detail_item.h"
@@ -42,7 +43,6 @@
 #import "ios/chrome/browser/ui/settings/settings_navigation_controller.h"
 #import "ios/chrome/browser/ui/settings/sync_encryption_collection_view_controller.h"
 #import "ios/chrome/browser/ui/settings/sync_encryption_passphrase_collection_view_controller.h"
-#import "ios/chrome/browser/ui/settings/utils/resized_avatar_cache.h"
 #import "ios/chrome/browser/ui/sync/sync_util.h"
 #import "ios/chrome/browser/ui/uikit_ui_util.h"
 #include "ios/chrome/grit/ios_strings.h"
diff --git a/ios/chrome/browser/ui/settings/utils/BUILD.gn b/ios/chrome/browser/ui/settings/utils/BUILD.gn
index 0a732ce..c8754f8d 100644
--- a/ios/chrome/browser/ui/settings/utils/BUILD.gn
+++ b/ios/chrome/browser/ui/settings/utils/BUILD.gn
@@ -10,8 +10,6 @@
     "observable_boolean.h",
     "pref_backed_boolean.h",
     "pref_backed_boolean.mm",
-    "resized_avatar_cache.h",
-    "resized_avatar_cache.mm",
   ]
   deps = [
     "//base",
diff --git a/ios/clean/chrome/browser/model/BUILD.gn b/ios/clean/chrome/browser/model/BUILD.gn
index db5f628..5418110 100644
--- a/ios/clean/chrome/browser/model/BUILD.gn
+++ b/ios/clean/chrome/browser/model/BUILD.gn
@@ -8,6 +8,8 @@
     "browser.mm",
     "browser_list.h",
     "browser_list.mm",
+    "browser_web_state_list_delegate.h",
+    "browser_web_state_list_delegate.mm",
   ]
   deps = [
     "//base",
diff --git a/ios/clean/chrome/browser/model/browser.h b/ios/clean/chrome/browser/model/browser.h
index 0e5349f..18abdd5 100644
--- a/ios/clean/chrome/browser/model/browser.h
+++ b/ios/clean/chrome/browser/model/browser.h
@@ -5,8 +5,12 @@
 #ifndef IOS_CLEAN_CHROME_BROWSER_MODEL_BROWSER_H_
 #define IOS_CLEAN_CHROME_BROWSER_MODEL_BROWSER_H_
 
+#include <memory>
+
 #include "base/macros.h"
-#include "ios/shared/chrome/browser/tabs/web_state_list.h"
+
+class WebStateList;
+class WebStateListDelegate;
 
 namespace ios {
 class ChromeBrowserState;
@@ -19,14 +23,15 @@
   explicit Browser(ios::ChromeBrowserState* browser_state);
   ~Browser();
 
-  WebStateList& web_state_list() { return web_state_list_; }
-  const WebStateList& web_state_list() const { return web_state_list_; }
+  WebStateList& web_state_list() { return *web_state_list_.get(); }
+  const WebStateList& web_state_list() const { return *web_state_list_.get(); }
 
   ios::ChromeBrowserState* browser_state() const { return browser_state_; }
 
  private:
-  WebStateList web_state_list_;
   ios::ChromeBrowserState* browser_state_;
+  std::unique_ptr<WebStateListDelegate> web_state_list_delegate_;
+  std::unique_ptr<WebStateList> web_state_list_;
 
   DISALLOW_COPY_AND_ASSIGN(Browser);
 };
diff --git a/ios/clean/chrome/browser/model/browser.mm b/ios/clean/chrome/browser/model/browser.mm
index ede26f6a..8724e3e 100644
--- a/ios/clean/chrome/browser/model/browser.mm
+++ b/ios/clean/chrome/browser/model/browser.mm
@@ -5,15 +5,21 @@
 #import "ios/clean/chrome/browser/model/browser.h"
 
 #include "base/logging.h"
+#include "base/memory/ptr_util.h"
+#import "ios/clean/chrome/browser/model/browser_web_state_list_delegate.h"
+#import "ios/shared/chrome/browser/tabs/web_state_list.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
 #endif
 
 Browser::Browser(ios::ChromeBrowserState* browser_state)
-    : web_state_list_(WebStateList::WebStateOwned),
-      browser_state_(browser_state) {
+    : browser_state_(browser_state) {
   DCHECK(browser_state_);
+  web_state_list_delegate_ =
+      base::MakeUnique<BrowserWebStateListDelegate>(this);
+  web_state_list_ = base::MakeUnique<WebStateList>(
+      web_state_list_delegate_.get(), WebStateList::WebStateOwned);
 }
 
 Browser::~Browser() = default;
diff --git a/ios/clean/chrome/browser/model/browser_list.h b/ios/clean/chrome/browser/model/browser_list.h
index 184718c..fe06217 100644
--- a/ios/clean/chrome/browser/model/browser_list.h
+++ b/ios/clean/chrome/browser/model/browser_list.h
@@ -5,6 +5,7 @@
 #ifndef IOS_CLEAN_CHROME_BROWSER_MODEL_BROWSER_LIST_H_
 #define IOS_CLEAN_CHROME_BROWSER_MODEL_BROWSER_LIST_H_
 
+#include <memory>
 #include <vector>
 
 #include "base/macros.h"
@@ -39,8 +40,8 @@
   void CloseBrowserAtIndex(int index);
 
  private:
-  std::vector<std::unique_ptr<Browser>> browsers_;
   ios::ChromeBrowserState* browser_state_;
+  std::vector<std::unique_ptr<Browser>> browsers_;
 
   DISALLOW_COPY_AND_ASSIGN(BrowserList);
 };
diff --git a/ios/clean/chrome/browser/model/browser_web_state_list_delegate.h b/ios/clean/chrome/browser/model/browser_web_state_list_delegate.h
new file mode 100644
index 0000000..dab5cf0f
--- /dev/null
+++ b/ios/clean/chrome/browser/model/browser_web_state_list_delegate.h
@@ -0,0 +1,28 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CLEAN_CHROME_BROWSER_MODEL_BROWSER_WEB_STATE_LIST_DELEGATE_H_
+#define IOS_CLEAN_CHROME_BROWSER_MODEL_BROWSER_WEB_STATE_LIST_DELEGATE_H_
+
+#include "base/macros.h"
+#import "ios/shared/chrome/browser/tabs/web_state_list_delegate.h"
+
+class Browser;
+
+// WebStateList delegate for the new architecture.
+class BrowserWebStateListDelegate : public WebStateListDelegate {
+ public:
+  explicit BrowserWebStateListDelegate(Browser* browser);
+  ~BrowserWebStateListDelegate() override;
+
+  // WebStateListDelegate implementation.
+  void WillAddWebState(web::WebState* web_state) override;
+
+ private:
+  Browser* browser_;
+
+  DISALLOW_COPY_AND_ASSIGN(BrowserWebStateListDelegate);
+};
+
+#endif  // IOS_CLEAN_CHROME_BROWSER_MODEL_BROWSER_WEB_STATE_LIST_DELEGATE_H_
diff --git a/ios/clean/chrome/browser/model/browser_web_state_list_delegate.mm b/ios/clean/chrome/browser/model/browser_web_state_list_delegate.mm
new file mode 100644
index 0000000..4f96ede
--- /dev/null
+++ b/ios/clean/chrome/browser/model/browser_web_state_list_delegate.mm
@@ -0,0 +1,20 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/clean/chrome/browser/model/browser_web_state_list_delegate.h"
+
+#include "base/logging.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+BrowserWebStateListDelegate::BrowserWebStateListDelegate(Browser* browser)
+    : browser_(browser) {
+  DCHECK(browser_);
+}
+
+BrowserWebStateListDelegate::~BrowserWebStateListDelegate() = default;
+
+void BrowserWebStateListDelegate::WillAddWebState(web::WebState* web_state) {}
diff --git a/ios/shared/chrome/browser/tabs/BUILD.gn b/ios/shared/chrome/browser/tabs/BUILD.gn
index 9dfe5783..af0ef72 100644
--- a/ios/shared/chrome/browser/tabs/BUILD.gn
+++ b/ios/shared/chrome/browser/tabs/BUILD.gn
@@ -6,6 +6,7 @@
   sources = [
     "web_state_list.h",
     "web_state_list.mm",
+    "web_state_list_delegate.h",
     "web_state_list_fast_enumeration_helper.h",
     "web_state_list_fast_enumeration_helper.mm",
     "web_state_list_metrics_observer.h",
@@ -26,6 +27,19 @@
   configs += [ "//build/config/compiler:enable_arc" ]
 }
 
+source_set("test_support") {
+  testonly = true
+  sources = [
+    "fake_web_state_list_delegate.h",
+    "fake_web_state_list_delegate.mm",
+  ]
+  deps = [
+    ":tabs",
+    "//base",
+  ]
+  configs += [ "//build/config/compiler:enable_arc" ]
+}
+
 source_set("unit_tests") {
   testonly = true
   sources = [
@@ -35,6 +49,7 @@
   ]
   deps = [
     ":tabs",
+    ":test_support",
     "//base",
     "//ios/web:test_support",
     "//net",
diff --git a/ios/shared/chrome/browser/tabs/fake_web_state_list_delegate.h b/ios/shared/chrome/browser/tabs/fake_web_state_list_delegate.h
new file mode 100644
index 0000000..ff499e9e
--- /dev/null
+++ b/ios/shared/chrome/browser/tabs/fake_web_state_list_delegate.h
@@ -0,0 +1,24 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_SHARED_CHROME_BROWSER_TABS_FAKE_WEB_STATE_LIST_DELEGATE_H_
+#define IOS_SHARED_CHROME_BROWSER_TABS_FAKE_WEB_STATE_LIST_DELEGATE_H_
+
+#include "base/macros.h"
+#import "ios/shared/chrome/browser/tabs/web_state_list_delegate.h"
+
+// Fake WebStateList delegate for tests.
+class FakeWebStateListDelegate : public WebStateListDelegate {
+ public:
+  FakeWebStateListDelegate();
+  ~FakeWebStateListDelegate() override;
+
+  // WebStateListDelegate implementation.
+  void WillAddWebState(web::WebState* web_state) override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(FakeWebStateListDelegate);
+};
+
+#endif  // IOS_SHARED_CHROME_BROWSER_TABS_FAKE_WEB_STATE_LIST_DELEGATE_H_
diff --git a/ios/shared/chrome/browser/tabs/fake_web_state_list_delegate.mm b/ios/shared/chrome/browser/tabs/fake_web_state_list_delegate.mm
new file mode 100644
index 0000000..75ee2577
--- /dev/null
+++ b/ios/shared/chrome/browser/tabs/fake_web_state_list_delegate.mm
@@ -0,0 +1,15 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/shared/chrome/browser/tabs/fake_web_state_list_delegate.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+FakeWebStateListDelegate::FakeWebStateListDelegate() = default;
+
+FakeWebStateListDelegate::~FakeWebStateListDelegate() = default;
+
+void FakeWebStateListDelegate::WillAddWebState(web::WebState* web_state) {}
diff --git a/ios/shared/chrome/browser/tabs/web_state_list.h b/ios/shared/chrome/browser/tabs/web_state_list.h
index ba3e9b8..e765455 100644
--- a/ios/shared/chrome/browser/tabs/web_state_list.h
+++ b/ios/shared/chrome/browser/tabs/web_state_list.h
@@ -13,6 +13,7 @@
 #include "base/observer_list.h"
 #include "ui/base/page_transition_types.h"
 
+class WebStateListDelegate;
 class WebStateListObserver;
 class WebStateListOrderController;
 
@@ -30,7 +31,7 @@
     WebStateOwned,
   };
 
-  explicit WebStateList(WebStateOwnership ownership = WebStateBorrowed);
+  WebStateList(WebStateListDelegate* delegate, WebStateOwnership ownership);
   ~WebStateList();
 
   // Returns whether the model is empty or not.
@@ -121,6 +122,8 @@
   static const int kInvalidIndex = -1;
 
  private:
+  class WebStateWrapper;
+
   // Sets the opener of any WebState that reference the WebState at the
   // specified index to null.
   void ClearOpenersReferencing(int index);
@@ -139,8 +142,14 @@
                                     bool use_group,
                                     int n) const;
 
-  class WebStateWrapper;
+  // The WebStateList delegate.
+  WebStateListDelegate* delegate_;
+
+  // Whether this WebStateList owns the WebState it hosts.
+  // TODO(crbug.com/546222): remove once this is always "owned".
   const WebStateOwnership web_state_ownership_;
+
+  // Wrappers to the WebStates hosted by the WebStateList.
   std::vector<std::unique_ptr<WebStateWrapper>> web_state_wrappers_;
 
   // An object that determines where new WebState should be inserted and where
diff --git a/ios/shared/chrome/browser/tabs/web_state_list.mm b/ios/shared/chrome/browser/tabs/web_state_list.mm
index 6c1434d8..5da7b0c 100644
--- a/ios/shared/chrome/browser/tabs/web_state_list.mm
+++ b/ios/shared/chrome/browser/tabs/web_state_list.mm
@@ -9,6 +9,7 @@
 
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
+#import "ios/shared/chrome/browser/tabs/web_state_list_delegate.h"
 #import "ios/shared/chrome/browser/tabs/web_state_list_observer.h"
 #import "ios/shared/chrome/browser/tabs/web_state_list_order_controller.h"
 #import "ios/web/public/navigation_manager.h"
@@ -87,9 +88,13 @@
   return opener_last_committed_index_ == opener_navigation_index;
 }
 
-WebStateList::WebStateList(WebStateOwnership ownership)
-    : web_state_ownership_(ownership),
-      order_controller_(base::MakeUnique<WebStateListOrderController>(this)) {}
+WebStateList::WebStateList(WebStateListDelegate* delegate,
+                           WebStateOwnership ownership)
+    : delegate_(delegate),
+      web_state_ownership_(ownership),
+      order_controller_(base::MakeUnique<WebStateListOrderController>(this)) {
+  DCHECK(delegate_);
+}
 
 WebStateList::~WebStateList() {
   // Once WebStateList owns the WebState and has a CloseWebStateAt() method,
@@ -153,6 +158,8 @@
                                   web::WebState* web_state,
                                   web::WebState* opener) {
   DCHECK(ContainsIndex(index) || index == count());
+  delegate_->WillAddWebState(web_state);
+
   web_state_wrappers_.insert(web_state_wrappers_.begin() + index,
                              base::MakeUnique<WebStateWrapper>(web_state));
 
@@ -207,6 +214,8 @@
                                                web::WebState* web_state,
                                                web::WebState* opener) {
   DCHECK(ContainsIndex(index));
+  delegate_->WillAddWebState(web_state);
+
   ClearOpenersReferencing(index);
 
   auto& web_state_wrapper = web_state_wrappers_[index];
diff --git a/ios/shared/chrome/browser/tabs/web_state_list_delegate.h b/ios/shared/chrome/browser/tabs/web_state_list_delegate.h
new file mode 100644
index 0000000..c1968bb
--- /dev/null
+++ b/ios/shared/chrome/browser/tabs/web_state_list_delegate.h
@@ -0,0 +1,30 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_SHARED_CHROME_BROWSER_TABS_WEB_STATE_LIST_DELEGATE_H_
+#define IOS_SHARED_CHROME_BROWSER_TABS_WEB_STATE_LIST_DELEGATE_H_
+
+#include "base/macros.h"
+
+namespace web {
+class WebState;
+}
+
+// A delegate interface that the WebStateList uses to perform work that it
+// cannot do itself such as attaching tab helpers, ...
+class WebStateListDelegate {
+ public:
+  WebStateListDelegate() = default;
+  virtual ~WebStateListDelegate() = default;
+
+  // Notifies the delegate that the specified WebState will be added to the
+  // WebStateList (via insertion/appending/replacing existing) and allows it
+  // to do any preparation that it deems necessary.
+  virtual void WillAddWebState(web::WebState* web_state) = 0;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(WebStateListDelegate);
+};
+
+#endif  // IOS_SHARED_CHROME_BROWSER_TABS_WEB_STATE_LIST_DELEGATE_H_
diff --git a/ios/shared/chrome/browser/tabs/web_state_list_fast_enumeration_helper_unittest.mm b/ios/shared/chrome/browser/tabs/web_state_list_fast_enumeration_helper_unittest.mm
index 58fb791..95edc1b 100644
--- a/ios/shared/chrome/browser/tabs/web_state_list_fast_enumeration_helper_unittest.mm
+++ b/ios/shared/chrome/browser/tabs/web_state_list_fast_enumeration_helper_unittest.mm
@@ -6,6 +6,7 @@
 
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
+#import "ios/shared/chrome/browser/tabs/fake_web_state_list_delegate.h"
 #import "ios/shared/chrome/browser/tabs/web_state_list.h"
 #import "ios/web/public/test/fakes/test_web_state.h"
 #import "net/base/mac/url_conversions.h"
@@ -40,7 +41,8 @@
 class WebStateListFastEnumerationHelperTest : public PlatformTest {
  public:
   WebStateListFastEnumerationHelperTest()
-      : web_state_list_(WebStateList::WebStateOwned) {}
+      : web_state_list_(&web_state_list_delegate_,
+                        WebStateList::WebStateOwned) {}
 
   NSArray* ArrayFromWebStateList() {
     id<WebStateProxyFactory> proxy =
@@ -72,6 +74,7 @@
   }
 
  private:
+  FakeWebStateListDelegate web_state_list_delegate_;
   WebStateList web_state_list_;
 
   DISALLOW_COPY_AND_ASSIGN(WebStateListFastEnumerationHelperTest);
diff --git a/ios/shared/chrome/browser/tabs/web_state_list_order_controller_unittest.mm b/ios/shared/chrome/browser/tabs/web_state_list_order_controller_unittest.mm
index 934c4d6..61b9cb5 100644
--- a/ios/shared/chrome/browser/tabs/web_state_list_order_controller_unittest.mm
+++ b/ios/shared/chrome/browser/tabs/web_state_list_order_controller_unittest.mm
@@ -6,6 +6,7 @@
 
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
+#import "ios/shared/chrome/browser/tabs/fake_web_state_list_delegate.h"
 #import "ios/shared/chrome/browser/tabs/web_state_list.h"
 #import "ios/web/public/test/fakes/test_navigation_manager.h"
 #import "ios/web/public/test/fakes/test_web_state.h"
@@ -34,10 +35,11 @@
 class WebStateListOrderControllerTest : public PlatformTest {
  public:
   WebStateListOrderControllerTest()
-      : web_state_list_(WebStateList::WebStateOwned),
+      : web_state_list_(&web_state_list_delegate_, WebStateList::WebStateOwned),
         order_controller_(&web_state_list_) {}
 
  protected:
+  FakeWebStateListDelegate web_state_list_delegate_;
   WebStateList web_state_list_;
   WebStateListOrderController order_controller_;
 
diff --git a/ios/shared/chrome/browser/tabs/web_state_list_unittest.mm b/ios/shared/chrome/browser/tabs/web_state_list_unittest.mm
index 5467429..f2e9070 100644
--- a/ios/shared/chrome/browser/tabs/web_state_list_unittest.mm
+++ b/ios/shared/chrome/browser/tabs/web_state_list_unittest.mm
@@ -7,6 +7,7 @@
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
 #include "base/supports_user_data.h"
+#import "ios/shared/chrome/browser/tabs/fake_web_state_list_delegate.h"
 #import "ios/shared/chrome/browser/tabs/web_state_list_observer.h"
 #import "ios/web/public/test/fakes/test_navigation_manager.h"
 #import "ios/web/public/test/fakes/test_web_state.h"
@@ -139,13 +140,16 @@
 
 class WebStateListTest : public PlatformTest {
  public:
-  WebStateListTest() : web_state_list_(WebStateList::WebStateOwned) {
+  WebStateListTest()
+      : web_state_list_(&web_state_list_delegate_,
+                        WebStateList::WebStateOwned) {
     web_state_list_.AddObserver(&observer_);
   }
 
   ~WebStateListTest() override { web_state_list_.RemoveObserver(&observer_); }
 
  protected:
+  FakeWebStateListDelegate web_state_list_delegate_;
   WebStateList web_state_list_;
   WebStateListTestObserver observer_;
 
@@ -390,8 +394,9 @@
       &kSupportsUserDataDeathGuardKey,
       base::MakeUnique<SupportsUserDataDeathGuard>(&web_state_was_killed));
 
-  auto web_state_list =
-      base::MakeUnique<WebStateList>(WebStateList::WebStateBorrowed);
+  FakeWebStateListDelegate web_state_list_delegate;
+  auto web_state_list = base::MakeUnique<WebStateList>(
+      &web_state_list_delegate, WebStateList::WebStateBorrowed);
   web_state_list->InsertWebState(0, test_web_state.get(), nullptr);
   EXPECT_FALSE(web_state_was_killed);
 
@@ -406,8 +411,9 @@
       &kSupportsUserDataDeathGuardKey,
       base::MakeUnique<SupportsUserDataDeathGuard>(&web_state_was_killed));
 
-  auto web_state_list =
-      base::MakeUnique<WebStateList>(WebStateList::WebStateOwned);
+  FakeWebStateListDelegate web_state_list_delegate;
+  auto web_state_list = base::MakeUnique<WebStateList>(
+      &web_state_list_delegate, WebStateList::WebStateOwned);
   web_state_list->InsertWebState(0, test_web_state.release(), nullptr);
   EXPECT_FALSE(web_state_was_killed);
 
diff --git a/media/filters/ffmpeg_audio_decoder.cc b/media/filters/ffmpeg_audio_decoder.cc
index e3560ff..06233eaa 100644
--- a/media/filters/ffmpeg_audio_decoder.cc
+++ b/media/filters/ffmpeg_audio_decoder.cc
@@ -45,8 +45,8 @@
 // Called by FFmpeg's allocation routine to free a buffer. |opaque| is the
 // AudioBuffer allocated, so unref it.
 static void ReleaseAudioBufferImpl(void* opaque, uint8_t* data) {
-  scoped_refptr<AudioBuffer> buffer;
-  buffer.swap(reinterpret_cast<AudioBuffer**>(&opaque));
+  if (opaque)
+    static_cast<AudioBuffer*>(opaque)->Release();
 }
 
 // Called by FFmpeg's allocation routine to allocate a buffer. Uses
@@ -124,8 +124,8 @@
 
   // Now create an AVBufferRef for the data just allocated. It will own the
   // reference to the AudioBuffer object.
-  void* opaque = NULL;
-  buffer.swap(reinterpret_cast<AudioBuffer**>(&opaque));
+  AudioBuffer* opaque = buffer.get();
+  opaque->AddRef();
   frame->buf[0] = av_buffer_create(
       frame->data[0], buffer_size_in_bytes, ReleaseAudioBufferImpl, opaque, 0);
   return 0;
diff --git a/media/filters/ffmpeg_video_decoder.cc b/media/filters/ffmpeg_video_decoder.cc
index 189c16e..606968b 100644
--- a/media/filters/ffmpeg_video_decoder.cc
+++ b/media/filters/ffmpeg_video_decoder.cc
@@ -102,8 +102,8 @@
 }
 
 static void ReleaseVideoBufferImpl(void* opaque, uint8_t* data) {
-  scoped_refptr<VideoFrame> video_frame;
-  video_frame.swap(reinterpret_cast<VideoFrame**>(&opaque));
+  if (opaque)
+    static_cast<VideoFrame*>(opaque)->Release();
 }
 
 // static
@@ -206,8 +206,8 @@
 
   // Now create an AVBufferRef for the data just allocated. It will own the
   // reference to the VideoFrame object.
-  void* opaque = NULL;
-  video_frame.swap(reinterpret_cast<VideoFrame**>(&opaque));
+  VideoFrame* opaque = video_frame.get();
+  opaque->AddRef();
   frame->buf[0] =
       av_buffer_create(frame->data[0],
                        VideoFrame::AllocationSize(format, coded_size),
diff --git a/services/ui/public/cpp/client_compositor_frame_sink.cc b/services/ui/public/cpp/client_compositor_frame_sink.cc
index 7f512e3f..da44887c 100644
--- a/services/ui/public/cpp/client_compositor_frame_sink.cc
+++ b/services/ui/public/cpp/client_compositor_frame_sink.cc
@@ -5,7 +5,9 @@
 #include "services/ui/public/cpp/client_compositor_frame_sink.h"
 
 #include "base/bind.h"
+#include "base/command_line.h"
 #include "base/memory/ptr_util.h"
+#include "cc/base/switches.h"
 #include "cc/output/compositor_frame.h"
 #include "cc/output/compositor_frame_sink_client.h"
 
@@ -61,6 +63,13 @@
   cc::CompositorFrameSink::DetachFromClient();
 }
 
+void ClientCompositorFrameSink::SetLocalSurfaceId(
+    const cc::LocalSurfaceId& local_surface_id) {
+  DCHECK(local_surface_id.is_valid());
+  DCHECK(enable_surface_synchronization_);
+  local_surface_id_ = local_surface_id;
+}
+
 void ClientCompositorFrameSink::SubmitCompositorFrame(
     cc::CompositorFrame frame) {
   DCHECK(thread_checker_);
@@ -71,12 +80,13 @@
   gfx::Size frame_size = last_submitted_frame_size_;
   if (!frame.render_pass_list.empty())
     frame_size = frame.render_pass_list.back()->output_rect.size();
-  if (!local_surface_id_.is_valid() || frame_size != last_submitted_frame_size_)
+  if (!enable_surface_synchronization_ &&
+      (!local_surface_id_.is_valid() ||
+       frame_size != last_submitted_frame_size_)) {
     local_surface_id_ = id_allocator_.GenerateId();
-
+  }
   compositor_frame_sink_->SubmitCompositorFrame(local_surface_id_,
                                                 std::move(frame));
-
   last_submitted_frame_size_ = frame_size;
 }
 
@@ -92,7 +102,11 @@
                               nullptr),
       compositor_frame_sink_info_(std::move(compositor_frame_sink_info)),
       client_request_(std::move(client_request)),
-      frame_sink_id_(frame_sink_id) {}
+      frame_sink_id_(frame_sink_id) {
+  enable_surface_synchronization_ =
+      base::CommandLine::ForCurrentProcess()->HasSwitch(
+          cc::switches::kEnableSurfaceSynchronization);
+}
 
 void ClientCompositorFrameSink::DidReceiveCompositorFrameAck() {
   DCHECK(thread_checker_);
diff --git a/services/ui/public/cpp/client_compositor_frame_sink.h b/services/ui/public/cpp/client_compositor_frame_sink.h
index ce0a3c0..37de018 100644
--- a/services/ui/public/cpp/client_compositor_frame_sink.h
+++ b/services/ui/public/cpp/client_compositor_frame_sink.h
@@ -36,6 +36,7 @@
   // cc::CompositorFrameSink implementation.
   bool BindToClient(cc::CompositorFrameSinkClient* client) override;
   void DetachFromClient() override;
+  void SetLocalSurfaceId(const cc::LocalSurfaceId& local_surface_id) override;
   void SubmitCompositorFrame(cc::CompositorFrame frame) override;
 
  private:
@@ -68,6 +69,7 @@
       client_binding_;
   std::unique_ptr<base::ThreadChecker> thread_checker_;
   const cc::FrameSinkId frame_sink_id_;
+  bool enable_surface_synchronization_ = false;
 
   DISALLOW_COPY_AND_ASSIGN(ClientCompositorFrameSink);
 };
diff --git a/services/ui/surfaces/display_compositor.cc b/services/ui/surfaces/display_compositor.cc
index 4809c17..9e10fde 100644
--- a/services/ui/surfaces/display_compositor.cc
+++ b/services/ui/surfaces/display_compositor.cc
@@ -67,6 +67,16 @@
   std::unique_ptr<cc::Display> display =
       CreateDisplay(frame_sink_id, surface_handle, begin_frame_source.get());
 
+  // Lazily inject a SurfaceDependencyTracker into SurfaceManager if surface
+  // synchronization is enabled.
+  if (!manager_.dependency_tracker() &&
+      base::CommandLine::ForCurrentProcess()->HasSwitch(
+          cc::switches::kEnableSurfaceSynchronization)) {
+    std::unique_ptr<cc::SurfaceDependencyTracker> dependency_tracker(
+        new cc::SurfaceDependencyTracker(&manager_, begin_frame_source.get()));
+    manager_.SetDependencyTracker(std::move(dependency_tracker));
+  }
+
   compositor_frame_sinks_[frame_sink_id] =
       base::MakeUnique<display_compositor::GpuRootCompositorFrameSink>(
           this, &manager_, frame_sink_id, std::move(display),
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index c0993fc2..197f0b5 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -2860,6 +2860,22 @@
             ]
         }
     ],
+    "V8Ignition": [
+        {
+            "platforms": [
+                "android",
+                "chromeos",
+                "linux",
+                "mac",
+                "win"
+            ],
+            "experiments": [
+                {
+                    "name": "Future"
+                }
+            ]
+        }
+    ],
     "ViewsSimplifiedFullscreenUI": [
         {
             "platforms": [
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/canvas-Float32ImageData-constructor.html b/third_party/WebKit/LayoutTests/fast/canvas/canvas-Float32ImageData-constructor.html
deleted file mode 100644
index 3ec49e4..0000000
--- a/third_party/WebKit/LayoutTests/fast/canvas/canvas-Float32ImageData-constructor.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<!DOCTYPE html>
-<body>
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
-<script src="resources/canvas-Float32ImageData.js"></script>
-</body>
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/canvas-Float32ImageData-workers.html b/third_party/WebKit/LayoutTests/fast/canvas/canvas-Float32ImageData-workers.html
deleted file mode 100644
index b3c97567..0000000
--- a/third_party/WebKit/LayoutTests/fast/canvas/canvas-Float32ImageData-workers.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<!DOCTYPE html>
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
-<script>
-fetch_tests_from_worker(new Worker("resources/canvas-Float32ImageData-workers.js"));
-</script>
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/color-space/float32ImageData-colorSpace.html b/third_party/WebKit/LayoutTests/fast/canvas/color-space/float32ImageData-colorSpace.html
deleted file mode 100644
index 5731c30..0000000
--- a/third_party/WebKit/LayoutTests/fast/canvas/color-space/float32ImageData-colorSpace.html
+++ /dev/null
@@ -1,27 +0,0 @@
-<!DOCTYPE html>
-<body>
-<script src="../../../resources/testharness.js"></script>
-<script src="../../../resources/testharnessreport.js"></script>
-<script>
-
-// RGBA(255,0,0,255) -> LinearRGB(0x3c00, 0x0, 0x0, 0x3c00)
-var data = new Float32Array([0x00003c00, 0x0, 0x0, 0x00003c00]);
-
-test(function() {
-
-  assert_equals((new Float32ImageData(1, 1)).colorSpace, "linear-rgb", "The default color space for Float32ImageData is linear-rgb.");
-  assert_equals((new Float32ImageData(1, 1, "linear-rgb")).colorSpace, "linear-rgb", "The color space read from Float32ImageData is the one that was set.");
-  assert_throws("NotSupportedError", function() {fImageData = new Float32ImageData(1, 1, "legacy-srgb");}, "Legacy SRGB is not supported in Float32ImageData.");
-  assert_throws("NotSupportedError", function() {fImageData = new Float32ImageData(1, 1, "srgb");}, "SRGB is not supported in Float32ImageData.");
-  assert_throws(null, function() {fImageData = new Float32ImageData(1, 1, "undefined");}, "Only members of ImageDataColorSpace enum are processed in Float32ImageData constructor.");
-
-  assert_equals((new Float32ImageData(data, 1, 1)).colorSpace, "linear-rgb", "The default color space for Float32ImageData is linear-rgb.");
-  assert_equals((new Float32ImageData(data, 1, 1, "linear-rgb")).colorSpace, "linear-rgb", "The color space read from Float32ImageData is the one that was set.");
-  assert_throws("NotSupportedError", function() {fImageData = new Float32ImageData(data, 1, 1, "legacy-srgb");}, "Legacy SRGB is not supported in Float32ImageData.");
-  assert_throws("NotSupportedError", function() {fImageData = new Float32ImageData(data, 1, 1, "srgb");}, "SRGB is not supported in Float32ImageData.");
-  assert_throws(null, function() {fImageData = new Float32ImageData(data, 1, 1, "undefined");}, "Only members of ImageDataColorSpace enum are processed in Float32ImageData constructor.");
-
-}, 'This test examines the correct behavior of Float32ImageData API in setting and getting ImageDataColorSpace.');
-
-</script>
-</body>
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/color-space/imageData-colorSpace.html b/third_party/WebKit/LayoutTests/fast/canvas/color-space/imageData-colorSpace.html
index a170bc6..2562429 100644
--- a/third_party/WebKit/LayoutTests/fast/canvas/color-space/imageData-colorSpace.html
+++ b/third_party/WebKit/LayoutTests/fast/canvas/color-space/imageData-colorSpace.html
@@ -4,46 +4,69 @@
 <script src="../../../resources/testharnessreport.js"></script>
 <script>
 
-var data = new Uint8ClampedArray([255, 0, 0, 255]);
+var dataU8 = new Uint8ClampedArray([255, 192, 128, 64]);
+var dataU16 = new Uint16Array([65535, 256*192, 256*128, 256*64]);
+var dataF32 = new Float32Array([1.0, 0.75, 0.5, 0.25]);
 
-function createImageDataAndGetColorSpace(colorSpace) {
-  experimental = new ImageData(1,1); 
-  imageData = experimental.createImageData(1, 1, colorSpace)
-  return imageData.colorSpace;
+function checkDataTypeAgainstColorSettings(data, colorSettings) {
+  if (colorSettings.storageFormat == "uint8")
+    assert_equals(Object.prototype.toString.call(data), "[object Uint8ClampedArray]");
+  else if (colorSettings.storageFormat == "uint16")
+    assert_equals(Object.prototype.toString.call(data), "[object Uint16Array]");
+  else if (colorSettings.storageFormat == "float32")
+    assert_equals(Object.prototype.toString.call(data), "[object Float32Array]");
 }
 
-function createWithDataAndGetColorSpaceW(colorSpace) {
-  experimental = new ImageData(1,1); 
-  imageData = experimental.createImageData(data, 1, colorSpace)
-  return imageData.colorSpace;
+function checkColorSettings(colorSettings, expectedColorSettings) {
+  assert_equals(colorSettings.colorSpace, expectedColorSettings.colorSpace);
+  assert_equals(colorSettings.storageFormat, expectedColorSettings.storageFormat);
 }
 
-function createWithDataAndGetColorSpaceWH(colorSpace) {
-  experimental = new ImageData(1,1); 
-  imageData = experimental.createImageData(data, 1, 1, colorSpace)
-  return imageData.colorSpace;
+function runTest(colorSettings, expectedColorSettings) {
+  experimental = new ImageData(1,1);
+  
+  imageData = experimental.createImageData(1, 1, colorSettings);
+  checkDataTypeAgainstColorSettings(imageData.dataUnion, colorSettings);
+  assert_array_equals(imageData.dataUnion, [0, 0, 0, 0]);
+  checkColorSettings(imageData.colorSettings, expectedColorSettings);
+
+  imageData = experimental.createImageData(dataU8, 1, 1, colorSettings);
+  assert_equals(Object.prototype.toString.call(imageData.dataUnion), "[object Uint8ClampedArray]");
+  assert_array_equals(imageData.dataUnion, dataU8);
+  checkColorSettings(imageData.colorSettings, expectedColorSettings);
+
+  imageData = experimental.createImageData(dataU16, 1, 1, colorSettings);
+  assert_equals(Object.prototype.toString.call(imageData.dataUnion), "[object Uint16Array]");
+  assert_array_equals(imageData.dataUnion, dataU16);
+  checkColorSettings(imageData.colorSettings, expectedColorSettings);
+
+  imageData = experimental.createImageData(dataF32, 1, 1, colorSettings);
+  assert_equals(Object.prototype.toString.call(imageData.dataUnion), "[object Float32Array]");
+  assert_array_equals(imageData.dataUnion, dataF32);
+  checkColorSettings(imageData.colorSettings, expectedColorSettings);
 }
 
-test(function() {
-  assert_equals((new ImageData(1,1)).colorSpace, "legacy-srgb", "The default color space for ImageData is legacy-srgb.");
-  assert_equals(createImageDataAndGetColorSpace("legacy-srgb"), "legacy-srgb", "The color space read from ImageData is the one that was set.");
-  assert_equals(createImageDataAndGetColorSpace("srgb"), "srgb", "The color space read from ImageData is the one that was set.");
-  assert_throws("NotSupportedError", function() {createImageDataAndGetColorSpace("linear-rgb");}, "Linear RGB is not supported in ImageData.");
-  assert_throws(null, function() {createImageDataAndGetColorSpace("undefined");}, "Only members of ImageDataColorSpace enum are processed in ImageData constructor.");
+var testScenarios = [
+	["Test default color settings: {undefined, undefined} -> {srgb, uint8}", {}, {colorSpace: "srgb", storageFormat: "uint8"}],
+  
+	["Test default color space: {undefined, float32} -> {srgb, float32}", {storageFormat: "float32"}, {colorSpace: "srgb", storageFormat: "float32"}],
+	["Test default storage format: {srgb, undefined} -> {srgb, uint8}", {colorSpace: "srgb"}, {colorSpace: "srgb", storageFormat: "uint8"}],
+  
+	["Test color settings: {srgb, uint8}", {colorSpace: "srgb", storageFormat: "uint8"}, {colorSpace: "srgb", storageFormat: "uint8"}],
+	["Test color settings: {srgb, uint16}", {colorSpace: "srgb", storageFormat: "uint16"}, {colorSpace: "srgb", storageFormat: "uint16"}],
+	["Test color settings: {srgb, float32}", {colorSpace: "srgb", storageFormat: "float32"}, {colorSpace: "srgb", storageFormat: "float32"}],
+  
+	["Test color settings: {rec2020, uint8}", {colorSpace: "rec2020", storageFormat: "uint8"}, {colorSpace: "rec2020", storageFormat: "uint8"}],
+	["Test color settings: {rec2020, uint16}", {colorSpace: "rec2020", storageFormat: "uint16"}, {colorSpace: "rec2020", storageFormat: "uint16"}],
+	["Test color settings: {rec2020, float32}", {colorSpace: "rec2020", storageFormat: "float32"}, {colorSpace: "rec2020", storageFormat: "float32"}],
 
-  assert_equals((new ImageData(data,1)).colorSpace, "legacy-srgb", "The default color space for ImageData is legacy-srgb.");
-  assert_equals(createWithDataAndGetColorSpaceW("legacy-srgb"), "legacy-srgb", "The color space read from ImageData is the one that was set.");
-  assert_equals(createWithDataAndGetColorSpaceW("srgb"), "srgb", "The color space read from ImageData is the one that was set.");
-  assert_throws("NotSupportedError", function() {createWithDataAndGetColorSpaceW("linear-rgb");}, "Linear RGB is not supported in ImageData.");
-  assert_throws(null, function() {createWithDataAndGetColorSpaceW("undefined");}, "Only members of ImageDataColorSpace enum are processed in ImageData constructor.");
+	["Test color settings: {p3, uint8}", {colorSpace: "p3", storageFormat: "uint8"}, {colorSpace: "p3", storageFormat: "uint8"}],
+	["Test color settings: {p3, uint16}", {colorSpace: "p3", storageFormat: "uint16"}, {colorSpace: "p3", storageFormat: "uint16"}],
+	["Test color settings: {p3, float32}", {colorSpace: "p3", storageFormat: "float32"}, {colorSpace: "p3", storageFormat: "float32"}],
 
-  assert_equals((new ImageData(data,1, 1)).colorSpace, "legacy-srgb", "The default color space for ImageData is legacy-srgb.");
-  assert_equals(createWithDataAndGetColorSpaceWH("legacy-srgb"), "legacy-srgb", "The color space read from ImageData is the one that was set.");
-  assert_equals(createWithDataAndGetColorSpaceWH("srgb"), "srgb", "The color space read from ImageData is the one that was set.");
-  assert_throws("NotSupportedError", function() {createWithDataAndGetColorSpaceWH("linear-rgb");}, "Linear RGB is not supported in ImageData.");
-  assert_throws(null, function() {createWithDataAndGetColorSpaceWH("undefined");}, "Only members of ImageDataColorSpace enum are processed in ImageData constructor.");
+];
 
-}, 'This test examines the correct behavior of createImageData API in setting and getting ImageData.colorSpace.');
+generate_tests(runTest, testScenarios);
 
 </script>
 </body>
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/resources/canvas-Float32ImageData-workers.js b/third_party/WebKit/LayoutTests/fast/canvas/resources/canvas-Float32ImageData-workers.js
deleted file mode 100644
index 7c872b55..0000000
--- a/third_party/WebKit/LayoutTests/fast/canvas/resources/canvas-Float32ImageData-workers.js
+++ /dev/null
@@ -1,2 +0,0 @@
-importScripts('../../../resources/testharness.js', 'canvas-Float32ImageData.js');
-done();
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/resources/canvas-Float32ImageData.js b/third_party/WebKit/LayoutTests/fast/canvas/resources/canvas-Float32ImageData.js
deleted file mode 100644
index 838297b0..0000000
--- a/third_party/WebKit/LayoutTests/fast/canvas/resources/canvas-Float32ImageData.js
+++ /dev/null
@@ -1,121 +0,0 @@
-function setF16Color(float32ImageData, i, f16Color) {
-  var s = i * 4;
-  float32ImageData[s] = f16Color[0];
-  float32ImageData[s + 1] = f16Color[1];
-  float32ImageData[s + 2] = f16Color[2];
-  float32ImageData[s + 3] = f16Color[3];
-}
-
-function getF16Color(float32ImageData, i) {
-  var result = [];
-  var s = i * 4;
-  for (var j = 0; j < 4; j++) {
-    result[j] = float32ImageData[s + j];
-  }
-  return result;
-}
-
-function compareF16Colors(f16Color1, f16Color2) {
-  for (var j = 0; j < 4; j++)
-    if (f16Color1[j] != f16Color2[j])
-      return false;
-  return true;
-}
-
-test(function() {
-
-  float32ImageData = new Float32ImageData(100, 50);
-  assert_equals(float32ImageData.width, 100,
-      "The width of the float32ImageData should be the width we passed to the constructor.");
-  assert_equals(float32ImageData.height, 50,
-      "The height of the float32ImageData should be the height we passed to the constructor.");
-
-  var f16ColorData = getF16Color(float32ImageData.data, 4);
-  assert_equals(f16ColorData[0], 0,
-      "The default ImageData color is transparent black.");
-  assert_equals(f16ColorData[1], 0,
-      "The default ImageData color is transparent black.");
-  assert_equals(f16ColorData[2], 0,
-      "The default ImageData color is transparent black.");
-  assert_equals(f16ColorData[3], 0,
-      "The default ImageData color is transparent black.");
-
-  var testColor = new Float32Array([0x00003c00, 0x00003c01, 0x00003c02, 0x00003c03]);
-  setF16Color(float32ImageData.data, 4, testColor);
-  f16ColorData = getF16Color(float32ImageData.data, 4);
-  assert_equals(f16ColorData[0], 0x00003c00,
-      "The red component of f16 color is the value we set.");
-  assert_equals(f16ColorData[1], 0x00003c01,
-      "The green component of f16 color is the value we set.");
-  assert_equals(f16ColorData[2], 0x00003c02,
-      "The blue component of f16 color is the value we set.");
-  assert_equals(f16ColorData[3], 0x00003c03,
-      "The alpha component of f16 color is the value we set.");
-
-  assert_throws(null, function() {new Float32ImageData(10);},
-      "Float32ImageData constructor requires both width and height.");
-  assert_throws("IndexSizeError", function() {new Float32ImageData(0,10);},
-      "Float32ImageData width must be greater than zero.");
-  assert_throws("IndexSizeError", function() {new Float32ImageData(10,0);},
-      "Float32ImageData height must be greater than zero.");
-  assert_throws("IndexSizeError", function() {new Float32ImageData('width', 'height');},
-      "Float32ImageData width and height must be numbers.");
-  assert_throws("IndexSizeError", function() {new Float32ImageData(1 << 31, 1 << 31);},
-      "Float32ImageData width multiplied by height must be less than 2^30 to avoid buffer size overflow.");
-
-  assert_throws(null, function() {new Float32ImageData(new Float32Array(0));},
-      "The Float32Array passed to the constructor cannot have a length of zero.");
-  assert_throws("IndexSizeError", function() {new Float32ImageData(new Float32Array(27), 2);},
-      "The size of Float32Array passed to the constructor must be divisible by 4 * width.");
-  assert_throws("IndexSizeError", function() {new Float32ImageData(new Float32Array(28), 7, 0);},
-      "The size of Float32Array passed to the constructor must be equal to 4 * width * height.");
-  assert_throws(null, function() {new Float32ImageData(self, 4, 4);},
-      "The object passed to the constructor as data array should be of type Float32Array.");
-  assert_throws(null, function() {new Float32ImageData(null, 4, 4);},
-      "The object passed to the constructor as data array should be of type Float32Array.");
-  assert_throws("IndexSizeError", function() {new Float32ImageData(float32ImageData.data, 0);},
-      "The size of Float32Array passed to the constructor must be divisible by 4 * width.");
-  assert_throws("IndexSizeError", function() {new Float32ImageData(float32ImageData.data, 13);},
-      "The size of Float32Array passed to the constructor must be divisible by 4 * width.");
-  assert_throws("IndexSizeError", function() {new Float32ImageData(float32ImageData.data, 1 << 31);},
-      "The size of Float32Array passed to the constructor must be divisible by 4 * width.");
-  assert_throws("IndexSizeError", function() {new Float32ImageData(float32ImageData.data, 'biggish');},
-      "The width parameter must be a number.");
-  assert_throws("IndexSizeError", function() {new Float32ImageData(float32ImageData.data, 1 << 24, 1 << 31);},
-      "Float32ImageData width multiplied by height must be less than 2^30 to avoid buffer size overflow.");
-  assert_throws("IndexSizeError", function() {new Float32ImageData(float32ImageData.data, 1 << 31, 1 << 24);},
-      "Float32ImageData width multiplied by height must be less than 2^30 to avoid buffer size overflow.");
-  assert_equals((new Float32ImageData(new Float32Array(28), 7)).height, 1,
-      "The height must be equal to size of the data array divided by 4 * width.");
-
-  float32ImageDataFromData = new Float32ImageData(float32ImageData.data, 100);
-  assert_equals(float32ImageDataFromData.width, 100,
-      "The width of the float32ImageDataFromData should be the same as that of float32ImageData.");
-  assert_equals(float32ImageDataFromData.height, 50,
-      "The height of the float32ImageDataFromData should be the same as that of float32ImageData.");
-  assert_true(float32ImageDataFromData.data == float32ImageData.data,
-      "The pixel data buffer of float32ImageDataFromData should be the same as that of float32ImageData.");
-  assert_true(compareF16Colors(getF16Color(float32ImageDataFromData.data, 10),
-                               getF16Color(float32ImageData.data, 10)),
-      "The color of a pixel from float32ImageDataFromData should be the same as that of float32ImageData.");
-  setF16Color(float32ImageData.data, 10, testColor);
-  assert_true(compareF16Colors(getF16Color(float32ImageDataFromData.data, 10),
-                               getF16Color(float32ImageData.data, 10)),
-      "Setting the color of a pixel from float32ImageData must cascade to the same pixel of float32ImageDataFromData.");
-
-  var data = new Float32Array(400);
-  data[22] = 129;
-  float32ImageDataFromData = new Float32ImageData(data, 20, 5);
-  assert_equals(float32ImageDataFromData.width, 20,
-      "The width of the float32ImageData should be the width we passed to the constructor.");
-  assert_equals(float32ImageDataFromData.height, 5,
-      "The height of the Float32ImageData must be equal to size of the Float32Array divided by 4 * width.");
-  assert_true(float32ImageDataFromData.data == data,
-      "The pixel data buffer of float32ImageDataFromData should be the same buffer passed to the constructor.");
-  assert_true(compareF16Colors(getF16Color(float32ImageDataFromData.data, 2), getF16Color(data, 2)),
-      "The pixel data of float32ImageDataFromData should be the same as that of the buffer passed to the constructor.");
-  setF16Color(float32ImageDataFromData.data, 2, testColor);
-  assert_true(compareF16Colors(getF16Color(float32ImageDataFromData.data, 2), getF16Color(data, 2)),
-      "Setting the color of a pixel from float32ImageDataFromData must cascade to the same pixel of the buffer passed to the constructor.");
-
-}, 'This test examines the correct behavior of Float32ImageData API.');
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
index f0ca8386..c8397bd 100644
--- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -431,12 +431,6 @@
     method readAsBinaryString
     method readAsDataURL
     method readAsText
-interface Float32ImageData
-    getter colorSpace
-    getter data
-    getter height
-    getter width
-    method constructor
 interface ForeignFetchEvent : ExtendableEvent
     getter origin
     getter request
@@ -603,8 +597,9 @@
     method close
     method constructor
 interface ImageData
-    getter colorSpace
+    getter colorSettings
     getter data
+    getter dataUnion
     getter height
     getter width
     method constructor
diff --git a/third_party/WebKit/LayoutTests/media/deprecated-css-selectors-expected.txt b/third_party/WebKit/LayoutTests/media/deprecated-css-selectors-expected.txt
index d92153e4..4d8f5316c 100644
--- a/third_party/WebKit/LayoutTests/media/deprecated-css-selectors-expected.txt
+++ b/third_party/WebKit/LayoutTests/media/deprecated-css-selectors-expected.txt
@@ -1,9 +1,4 @@
 CONSOLE WARNING: -internal-media-controls-overlay-cast-button selector is deprecated and will be removed in M59, around June 2017. See https://www.chromestatus.com/features/5714245488476160 for more details.
-CONSOLE WARNING: -internal-media-controls-text-track-list* selectors is deprecated and will be removed in M59, around June 2017. See https://www.chromestatus.com/features/5661431349379072 for more details.
-CONSOLE WARNING: -internal-media-controls-text-track-list* selectors is deprecated and will be removed in M59, around June 2017. See https://www.chromestatus.com/features/5661431349379072 for more details.
-CONSOLE WARNING: -internal-media-controls-text-track-list* selectors is deprecated and will be removed in M59, around June 2017. See https://www.chromestatus.com/features/5661431349379072 for more details.
-CONSOLE WARNING: -internal-media-controls-text-track-list* selectors is deprecated and will be removed in M59, around June 2017. See https://www.chromestatus.com/features/5661431349379072 for more details.
-CONSOLE WARNING: -internal-media-controls-text-track-list* selectors is deprecated and will be removed in M59, around June 2017. See https://www.chromestatus.com/features/5661431349379072 for more details.
 This is a testharness.js-based test.
 PASS Test that -internal-media-controls-* deprecated selectors throw a warning 
 Harness: the test ran to completion.
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/stable/webexposed/global-interface-listing-expected.txt
index 2eb51d1..38229c4a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/stable/webexposed/global-interface-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -3139,7 +3139,6 @@
     method transferFromImageBitmap
 interface ImageData
     attribute @@toStringTag
-    getter colorSpace
     getter data
     getter height
     getter width
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/platform/win/virtual/stable/webexposed/global-interface-listing-expected.txt
index befe983..4bbc5f0e 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/stable/webexposed/global-interface-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -3068,7 +3068,6 @@
     method transferFromImageBitmap
 interface ImageData
     attribute @@toStringTag
-    getter colorSpace
     getter data
     getter height
     getter width
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/select/input-select-after-resize-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/select/input-select-after-resize-expected.png
deleted file mode 100644
index 122fef2a..0000000
--- a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/select/input-select-after-resize-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/svg/custom/svgdom-manipulation-of-svg-root-width-before-attach-expected.html b/third_party/WebKit/LayoutTests/svg/custom/svgdom-manipulation-of-svg-root-width-before-attach-expected.html
new file mode 100644
index 0000000..f718ea6
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/svg/custom/svgdom-manipulation-of-svg-root-width-before-attach-expected.html
@@ -0,0 +1,2 @@
+<!DOCTYPE html>
+<div style="width: 100px; height: 100px; background-color: green"></div>
diff --git a/third_party/WebKit/LayoutTests/svg/custom/svgdom-manipulation-of-svg-root-width-before-attach.html b/third_party/WebKit/LayoutTests/svg/custom/svgdom-manipulation-of-svg-root-width-before-attach.html
new file mode 100644
index 0000000..f35a91e3
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/svg/custom/svgdom-manipulation-of-svg-root-width-before-attach.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<style>
+svg { height: 200px }
+</style>
+<body>
+<script>
+var rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
+rect.setAttribute('width', '100');
+rect.setAttribute('height', '100');
+rect.setAttribute('fill', 'green');
+var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
+svg.appendChild(rect);
+svg.setAttribute('viewBox', '0 0 200 100');
+svg.setAttribute('preserveAspectRatio', 'xMinYMin');
+svg.width.baseVal.valueAsString = '200';
+document.body.appendChild(svg);
+</script>
diff --git a/third_party/WebKit/LayoutTests/svg/dom/SVGAngle-expected.txt b/third_party/WebKit/LayoutTests/svg/dom/SVGAngle-expected.txt
deleted file mode 100644
index 7204c1b4..0000000
--- a/third_party/WebKit/LayoutTests/svg/dom/SVGAngle-expected.txt
+++ /dev/null
@@ -1,209 +0,0 @@
-This test checks the SVGAngle API
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-
-Check initial angle values
-PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_UNSPECIFIED
-PASS angle.valueAsString is "0"
-PASS angle.value is 0
-PASS angle.valueInSpecifiedUnits is 0
-
-Check invalid arguments for 'convertToSpecifiedUnits'
-PASS angle.convertToSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_UNKNOWN) threw exception NotSupportedError: Failed to execute 'convertToSpecifiedUnits' on 'SVGAngle': Cannot convert to unknown or invalid units (0)..
-PASS angle.convertToSpecifiedUnits(-1) threw exception NotSupportedError: Failed to execute 'convertToSpecifiedUnits' on 'SVGAngle': Cannot convert to unknown or invalid units (65535)..
-PASS angle.convertToSpecifiedUnits(5) threw exception NotSupportedError: Failed to execute 'convertToSpecifiedUnits' on 'SVGAngle': Cannot convert to unknown or invalid units (5)..
-PASS angle.convertToSpecifiedUnits('aString') threw exception NotSupportedError: Failed to execute 'convertToSpecifiedUnits' on 'SVGAngle': Cannot convert to unknown or invalid units (0)..
-PASS angle.convertToSpecifiedUnits(angle) threw exception NotSupportedError: Failed to execute 'convertToSpecifiedUnits' on 'SVGAngle': Cannot convert to unknown or invalid units (0)..
-PASS angle.convertToSpecifiedUnits(svgElement) threw exception NotSupportedError: Failed to execute 'convertToSpecifiedUnits' on 'SVGAngle': Cannot convert to unknown or invalid units (0)..
-PASS angle.convertToSpecifiedUnits() threw exception TypeError: Failed to execute 'convertToSpecifiedUnits' on 'SVGAngle': 1 argument required, but only 0 present..
-PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_UNSPECIFIED
-
-Check valid arguments for 'convertToSpecifiedUnits', that should only modify the 'valueAsString'
-PASS angle.convertToSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_RAD) is undefined.
-PASS angle.valueAsString is "0rad"
-PASS angle.value is 0
-PASS angle.valueInSpecifiedUnits is 0
-PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_RAD
-PASS angle.convertToSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_GRAD) is undefined.
-PASS angle.valueAsString is "0grad"
-PASS angle.value is 0
-PASS angle.valueInSpecifiedUnits is 0
-PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_GRAD
-PASS angle.convertToSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_DEG) is undefined.
-PASS angle.valueAsString is "0deg"
-PASS angle.value is 0
-PASS angle.valueInSpecifiedUnits is 0
-PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_DEG
-PASS angle.convertToSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_UNSPECIFIED) is undefined.
-PASS angle.valueAsString is "0"
-PASS angle.value is 0
-PASS angle.valueInSpecifiedUnits is 0
-PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_UNSPECIFIED
-
-Check invalid arguments for 'newValueSpecifiedUnits'
-PASS angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_UNKNOWN, 50) threw exception NotSupportedError: Failed to execute 'newValueSpecifiedUnits' on 'SVGAngle': Cannot set value with unknown or invalid units (0)..
-PASS angle.newValueSpecifiedUnits(-1, 50) threw exception NotSupportedError: Failed to execute 'newValueSpecifiedUnits' on 'SVGAngle': Cannot set value with unknown or invalid units (65535)..
-PASS angle.newValueSpecifiedUnits(5, 50) threw exception NotSupportedError: Failed to execute 'newValueSpecifiedUnits' on 'SVGAngle': Cannot set value with unknown or invalid units (5)..
-PASS angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_DEG) threw exception TypeError: Failed to execute 'newValueSpecifiedUnits' on 'SVGAngle': 2 arguments required, but only 1 present..
-PASS angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_DEG, 'aString') threw exception TypeError: Failed to execute 'newValueSpecifiedUnits' on 'SVGAngle': The provided float value is non-finite..
-PASS angle.value is 0
-PASS angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_DEG, 0) is undefined.
-PASS angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_DEG, angle) threw exception TypeError: Failed to execute 'newValueSpecifiedUnits' on 'SVGAngle': The provided float value is non-finite..
-PASS angle.value is 0
-PASS angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_DEG, svgElement) threw exception TypeError: Failed to execute 'newValueSpecifiedUnits' on 'SVGAngle': The provided float value is non-finite..
-PASS angle.value is 0
-PASS angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_DEG, NaN) threw exception TypeError: Failed to execute 'newValueSpecifiedUnits' on 'SVGAngle': The provided float value is non-finite..
-PASS angle.value is 0
-PASS angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_DEG, Infinity) threw exception TypeError: Failed to execute 'newValueSpecifiedUnits' on 'SVGAngle': The provided float value is non-finite..
-PASS angle.value is 0
-PASS angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_DEG) threw exception TypeError: Failed to execute 'newValueSpecifiedUnits' on 'SVGAngle': 2 arguments required, but only 1 present..
-PASS angle.newValueSpecifiedUnits('aString', 4) threw exception NotSupportedError: Failed to execute 'newValueSpecifiedUnits' on 'SVGAngle': Cannot set value with unknown or invalid units (0)..
-PASS angle.newValueSpecifiedUnits(angle, 4) threw exception NotSupportedError: Failed to execute 'newValueSpecifiedUnits' on 'SVGAngle': Cannot set value with unknown or invalid units (0)..
-PASS angle.newValueSpecifiedUnits(svgElement, 4) threw exception NotSupportedError: Failed to execute 'newValueSpecifiedUnits' on 'SVGAngle': Cannot set value with unknown or invalid units (0)..
-PASS angle.newValueSpecifiedUnits('aString', 'aString') threw exception TypeError: Failed to execute 'newValueSpecifiedUnits' on 'SVGAngle': The provided float value is non-finite..
-PASS angle.newValueSpecifiedUnits(angle, angle) threw exception TypeError: Failed to execute 'newValueSpecifiedUnits' on 'SVGAngle': The provided float value is non-finite..
-PASS angle.newValueSpecifiedUnits(svgElement, svgElement) threw exception TypeError: Failed to execute 'newValueSpecifiedUnits' on 'SVGAngle': The provided float value is non-finite..
-PASS angle.newValueSpecifiedUnits() threw exception TypeError: Failed to execute 'newValueSpecifiedUnits' on 'SVGAngle': 2 arguments required, but only 0 present..
-PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_DEG
-
-Check valid arguments for 'newValueSpecifiedUnits', that should only modify the 'valueAsString'
-PASS angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_RAD, parseFloat(Math.PI.toFixed(5))) is undefined.
-PASS angle.valueAsString is "3.14159rad"
-PASS angle.value.toFixed(1) is "180.0"
-PASS angle.valueInSpecifiedUnits.toFixed(5) is Math.PI.toFixed(5)
-PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_RAD
-PASS angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_GRAD, 400) is undefined.
-PASS angle.valueAsString is "400grad"
-PASS angle.value.toFixed(1) is "360.0"
-PASS angle.valueInSpecifiedUnits is 400
-PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_GRAD
-PASS angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_DEG, 360) is undefined.
-PASS angle.valueAsString is "360deg"
-PASS angle.value is 360
-PASS angle.valueInSpecifiedUnits is 360
-PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_DEG
-PASS angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_UNSPECIFIED, 180) is undefined.
-PASS angle.valueAsString is "180"
-PASS angle.value is 180
-PASS angle.valueInSpecifiedUnits is 180
-PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_UNSPECIFIED
-
-Reset to initial angle state
-PASS angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_UNSPECIFIED, 0) is undefined.
-PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_UNSPECIFIED
-
-Check setting invalid 'valueAsString' arguments
-PASS angle.valueAsString = '10px' threw exception SyntaxError: Failed to set the 'valueAsString' property on 'SVGAngle': The value provided ('10px') is invalid..
-PASS angle.valueAsString is "0"
-PASS angle.value is 0
-PASS angle.valueInSpecifiedUnits is 0
-PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_UNSPECIFIED
-PASS angle.valueAsString = '10x' threw exception SyntaxError: Failed to set the 'valueAsString' property on 'SVGAngle': The value provided ('10x') is invalid..
-PASS angle.valueAsString is "0"
-PASS angle.value is 0
-PASS angle.valueInSpecifiedUnits is 0
-PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_UNSPECIFIED
-PASS angle.valueAsString = '5graD' threw exception SyntaxError: Failed to set the 'valueAsString' property on 'SVGAngle': The value provided ('5graD') is invalid..
-PASS angle.valueAsString is "0"
-PASS angle.value is 0
-PASS angle.valueInSpecifiedUnits is 0
-PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_UNSPECIFIED
-PASS angle.valueAsString = '5Rad' threw exception SyntaxError: Failed to set the 'valueAsString' property on 'SVGAngle': The value provided ('5Rad') is invalid..
-PASS angle.valueAsString is "0"
-PASS angle.value is 0
-PASS angle.valueInSpecifiedUnits is 0
-PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_UNSPECIFIED
-PASS angle.valueAsString = ',5 rad' threw exception SyntaxError: Failed to set the 'valueAsString' property on 'SVGAngle': The value provided (',5 rad') is invalid..
-PASS angle.valueAsString is "0"
-PASS angle.value is 0
-PASS angle.valueInSpecifiedUnits is 0
-PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_UNSPECIFIED
-PASS angle.valueAsString = null threw exception SyntaxError: Failed to set the 'valueAsString' property on 'SVGAngle': The value provided ('null') is invalid..
-PASS angle.valueAsString is "0"
-PASS angle.value is 0
-PASS angle.valueInSpecifiedUnits is 0
-PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_UNSPECIFIED
-
-Check setting invalid 'valueInSpecifiedUnits' arguments
-PASS angle.valueInSpecifiedUnits = 'test' threw exception TypeError: Failed to set the 'valueInSpecifiedUnits' property on 'SVGAngle': The provided float value is non-finite..
-PASS angle.value is 0
-PASS angle.valueInSpecifiedUnits is 0
-PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_UNSPECIFIED
-PASS angle.valueInSpecifiedUnits = 0 is 0
-PASS angle.valueInSpecifiedUnits = angle threw exception TypeError: Failed to set the 'valueInSpecifiedUnits' property on 'SVGAngle': The provided float value is non-finite..
-PASS angle.value is 0
-PASS angle.valueInSpecifiedUnits = NaN threw exception TypeError: Failed to set the 'valueInSpecifiedUnits' property on 'SVGAngle': The provided float value is non-finite..
-PASS angle.value is 0
-PASS angle.valueInSpecifiedUnits = Infinity threw exception TypeError: Failed to set the 'valueInSpecifiedUnits' property on 'SVGAngle': The provided float value is non-finite..
-PASS angle.value is 0
-PASS angle.valueInSpecifiedUnits is 0
-PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_UNSPECIFIED
-
-Check setting invalid 'value' arguments
-PASS angle.value = 0 is 0
-PASS angle.value = 'test' threw exception TypeError: Failed to set the 'value' property on 'SVGAngle': The provided float value is non-finite..
-PASS angle.value is 0
-PASS angle.valueInSpecifiedUnits is 0
-PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_UNSPECIFIED
-PASS angle.value = 0 is 0
-PASS angle.value = angle threw exception TypeError: Failed to set the 'value' property on 'SVGAngle': The provided float value is non-finite..
-PASS angle.value is 0
-PASS angle.value = NaN threw exception TypeError: Failed to set the 'value' property on 'SVGAngle': The provided float value is non-finite..
-PASS angle.value is 0
-PASS angle.value = Infinity threw exception TypeError: Failed to set the 'value' property on 'SVGAngle': The provided float value is non-finite..
-PASS angle.value is 0
-PASS angle.valueInSpecifiedUnits is 0
-PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_UNSPECIFIED
-
-Reset to angle in degree units
-PASS angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_DEG, 0) is undefined.
-PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_DEG
-
-Check setting valid 'value' arguments, assure that 'valueInSpecifiedUnits' and 'valueAsString' are synchronized
-PASS angle.value = 50 is 50
-PASS angle.valueInSpecifiedUnits is 50
-PASS angle.valueAsString is "50deg"
-PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_DEG
-
-Try modifiying the readonly 'unitType', needs to fail
-PASS angle.unitType = SVGAngle.SVG_ANGLETTYE_RAD is undefined.
-PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_DEG
-
-Check setting valid 'valueInSpecifiedUnits' arguments, assure that 'value' and 'valueAsString' are synchronized
-PASS angle.valueInSpecifiedUnits = 100 is 100
-PASS angle.value is 100
-PASS angle.valueAsString is "100deg"
-PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_DEG
-
-Check setting valid 'valueAsString' arguments, assure that 'value' and 'valueInSpecifiedUnits' are synchronized
-PASS angle.valueAsString = '200grad' is "200grad"
-PASS angle.valueInSpecifiedUnits is 200
-PASS angle.value.toFixed(1) is "180.0"
-PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_GRAD
-
-Now convert the GRAD value into a RAD value, and assure that all properties have been synchronized
-PASS angle.convertToSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_RAD) is undefined.
-PASS angle.value.toFixed(1) is "180.0"
-PASS angle.valueInSpecifiedUnits.toFixed(5) is "3.14159"
-PASS angle.valueAsString is "3.14159rad"
-PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_RAD
-
-Now try converting the RAD value into an unknown value, that should fail and throw
-PASS angle.convertToSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_UNKNOWN) threw exception NotSupportedError: Failed to execute 'convertToSpecifiedUnits' on 'SVGAngle': Cannot convert to unknown or invalid units (0)..
-PASS angle.value.toFixed(1) is "180.0"
-PASS angle.valueInSpecifiedUnits.toFixed(5) is "3.14159"
-PASS angle.valueAsString is "3.14159rad"
-PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_RAD
-
-Now convert the RAD value into a DEG value, and assure that all properties have been synchronized
-PASS angle.convertToSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_DEG) is undefined.
-PASS angle.value.toFixed(1) is "180.0"
-PASS angle.valueInSpecifiedUnits.toFixed(1) is "180.0"
-PASS angle.valueAsString is "180deg"
-PASS angle.unitType is SVGAngle.SVG_ANGLETYPE_DEG
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/WebKit/LayoutTests/svg/dom/SVGAngle.html b/third_party/WebKit/LayoutTests/svg/dom/SVGAngle.html
index d12930bb..a609edc 100644
--- a/third_party/WebKit/LayoutTests/svg/dom/SVGAngle.html
+++ b/third_party/WebKit/LayoutTests/svg/dom/SVGAngle.html
@@ -1,11 +1,241 @@
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<html>
-<head>
-<script src="../../resources/js-test.js"></script>
-</head>
-<body>
-<p id="description"></p>
-<div id="console"></div>
-<script src="script-tests/SVGAngle.js"></script>
-</body>
-</html>
+<!DOCTYPE HTML>
+<title>SVGAngle interface</title>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script>
+test(function() {
+  // This test checks the SVGAngle API.
+
+  var svgElement = document.createElementNS("http://www.w3.org/2000/svg", "svg");
+  var angle = svgElement.createSVGAngle();
+
+  // Check initial angle values.
+  assert_equals(angle.unitType, SVGAngle.SVG_ANGLETYPE_UNSPECIFIED);
+  assert_equals(angle.valueAsString, "0");
+  assert_equals(angle.value, 0);
+  assert_equals(angle.valueInSpecifiedUnits, 0);
+
+  // Spec: Raised if unitType is SVG_ANGLETYPE_UNKNOWN or not a valid unit type constant (one of the other SVG_ANGLETYPE_* constants defined on this interface).
+  // Check invalid arguments for 'convertToSpecifiedUnits'.
+  assert_throws("NotSupportedError", function() { angle.convertToSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_UNKNOWN); });
+  assert_throws("NotSupportedError", function() { angle.convertToSpecifiedUnits(-1); });
+  assert_throws("NotSupportedError", function() { angle.convertToSpecifiedUnits(5); });
+  // 'aString' converts to short 0 (through NaN) according to ECMA-262, ToUint16.
+  // Therefore this throws NOT_SUPPORTED_ERR.
+  assert_throws("NotSupportedError", function() { angle.convertToSpecifiedUnits('aString'); });
+  // Same here, via ToString conversion of object.
+  assert_throws("NotSupportedError", function() { angle.convertToSpecifiedUnits(angle); });
+  // Same here, via ToString conversion of object.
+  assert_throws("NotSupportedError", function() { angle.convertToSpecifiedUnits(svgElement); });
+  assert_throws(new TypeError(), function() { angle.convertToSpecifiedUnits(); });
+  assert_equals(angle.unitType, SVGAngle.SVG_ANGLETYPE_UNSPECIFIED);
+
+  // Check valid arguments for 'convertToSpecifiedUnits', that should only modify the 'valueAsString'");
+  angle.convertToSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_RAD);
+  assert_equals(angle.valueAsString, "0rad");
+  assert_equals(angle.value, 0);
+  assert_equals(angle.valueInSpecifiedUnits, 0);
+  assert_equals(angle.unitType, SVGAngle.SVG_ANGLETYPE_RAD);
+
+  angle.convertToSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_GRAD);
+  assert_equals(angle.valueAsString, "0grad");
+  assert_equals(angle.value, 0);
+  assert_equals(angle.valueInSpecifiedUnits, 0);
+  assert_equals(angle.unitType, SVGAngle.SVG_ANGLETYPE_GRAD);
+
+  angle.convertToSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_DEG);
+  assert_equals(angle.valueAsString, "0deg");
+  assert_equals(angle.value, 0);
+  assert_equals(angle.valueInSpecifiedUnits, 0);
+  assert_equals(angle.unitType, SVGAngle.SVG_ANGLETYPE_DEG);
+
+  angle.convertToSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_UNSPECIFIED);
+  assert_equals(angle.valueAsString, "0");
+  assert_equals(angle.value, 0);
+  assert_equals(angle.valueInSpecifiedUnits, 0);
+  assert_equals(angle.unitType, SVGAngle.SVG_ANGLETYPE_UNSPECIFIED);
+
+  // Spec: Raised if unitType is SVG_ANGLETYPE_UNKNOWN or not a valid unit type constant (one of the other SVG_ANGLETYPE_* constants defined on this interface).
+  // Check invalid arguments for 'newValueSpecifiedUnits'.
+  assert_throws("NotSupportedError", function() { angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_UNKNOWN, 50); });
+  assert_throws("NotSupportedError", function() { angle.newValueSpecifiedUnits(-1, 50); });
+  assert_throws("NotSupportedError", function() { angle.newValueSpecifiedUnits(5, 50); });
+  assert_throws(new TypeError(), function() { angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_DEG); });
+  assert_throws(new TypeError(), function() { angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_DEG, 'aString'); });
+  assert_equals(angle.value, 0);
+
+  angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_DEG, 0);
+  assert_throws(new TypeError(), function() { angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_DEG, angle); });
+  assert_equals(angle.value, 0);
+  assert_throws(new TypeError(), function() { angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_DEG, svgElement); });
+  assert_equals(angle.value, 0);
+  assert_throws(new TypeError(), function() { angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_DEG, NaN); });
+  assert_equals(angle.value, 0);
+  assert_throws(new TypeError(), function() { angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_DEG, Infinity); });
+  assert_equals(angle.value, 0);
+  assert_throws(new TypeError(), function() { angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_DEG); });
+
+  // All of the following unitType arguments convert to 0 (SVG_ANGLETYPE_UNKNOWN).
+  assert_throws("NotSupportedError", function() { angle.newValueSpecifiedUnits('aString', 4); });
+  assert_throws("NotSupportedError", function() { angle.newValueSpecifiedUnits(angle, 4); });
+  assert_throws("NotSupportedError", function() { angle.newValueSpecifiedUnits(svgElement, 4); });
+  assert_throws(new TypeError(), function() { angle.newValueSpecifiedUnits('aString', 'aString'); });
+  assert_throws(new TypeError(), function() { angle.newValueSpecifiedUnits(angle, angle); });
+  assert_throws(new TypeError(), function() { angle.newValueSpecifiedUnits(svgElement, svgElement); });
+  assert_throws(new TypeError(), function() { angle.newValueSpecifiedUnits(); });
+  assert_equals(angle.unitType, SVGAngle.SVG_ANGLETYPE_DEG);
+
+  // Check valid arguments for 'newValueSpecifiedUnits', that should only modify the 'valueAsString'.
+  angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_RAD, parseFloat(Math.PI.toFixed(5)));
+  assert_equals(angle.valueAsString, Math.PI.toFixed(5) + "rad");
+  assert_equals(angle.value.toFixed(1), "180.0");
+  assert_equals(angle.valueInSpecifiedUnits.toFixed(5), Math.PI.toFixed(5));
+  assert_equals(angle.unitType, SVGAngle.SVG_ANGLETYPE_RAD);
+
+  angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_GRAD, 400);
+  assert_equals(angle.valueAsString, "400grad");
+  assert_equals(angle.value.toFixed(1), "360.0");
+  assert_equals(angle.valueInSpecifiedUnits, 400);
+  assert_equals(angle.unitType, SVGAngle.SVG_ANGLETYPE_GRAD);
+
+  angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_DEG, 360);
+  assert_equals(angle.valueAsString, "360deg");
+  assert_equals(angle.value, 360);
+  assert_equals(angle.valueInSpecifiedUnits, 360);
+  assert_equals(angle.unitType, SVGAngle.SVG_ANGLETYPE_DEG);
+
+  angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_UNSPECIFIED, 180);
+  assert_equals(angle.valueAsString, "180");
+  assert_equals(angle.value, 180);
+  assert_equals(angle.valueInSpecifiedUnits, 180);
+  assert_equals(angle.unitType, SVGAngle.SVG_ANGLETYPE_UNSPECIFIED);
+
+  // Reset to initial angle state.
+  angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_UNSPECIFIED, 0);
+  assert_equals(angle.unitType, SVGAngle.SVG_ANGLETYPE_UNSPECIFIED);
+
+  // Spec: Raised if the assigned string cannot be parsed as a valid <angle>.
+  // Check setting invalid 'valueAsString' arguments.
+  assert_throws("SyntaxError", function() { angle.valueAsString = '10px'; });
+  assert_equals(angle.valueAsString, "0");
+  assert_equals(angle.value, 0);
+  assert_equals(angle.valueInSpecifiedUnits, 0);
+  assert_equals(angle.unitType, SVGAngle.SVG_ANGLETYPE_UNSPECIFIED);
+
+  assert_throws("SyntaxError", function() { angle.valueAsString = '10x'; });
+  assert_equals(angle.valueAsString, "0");
+  assert_equals(angle.value, 0);
+  assert_equals(angle.valueInSpecifiedUnits, 0);
+  assert_equals(angle.unitType, SVGAngle.SVG_ANGLETYPE_UNSPECIFIED);
+
+  assert_throws("SyntaxError", function() { angle.valueAsString = '5graD'; });
+  assert_equals(angle.valueAsString, "0");
+  assert_equals(angle.value, 0);
+  assert_equals(angle.valueInSpecifiedUnits, 0);
+  assert_equals(angle.unitType, SVGAngle.SVG_ANGLETYPE_UNSPECIFIED);
+
+  assert_throws("SyntaxError", function() { angle.valueAsString = '5Rad'; });
+  assert_equals(angle.valueAsString, "0");
+  assert_equals(angle.value, 0);
+  assert_equals(angle.valueInSpecifiedUnits, 0);
+  assert_equals(angle.unitType, SVGAngle.SVG_ANGLETYPE_UNSPECIFIED);
+
+  assert_throws("SyntaxError", function() { angle.valueAsString = ',5 rad'; });
+  assert_equals(angle.valueAsString, "0");
+  assert_equals(angle.value, 0);
+  assert_equals(angle.valueInSpecifiedUnits, 0);
+  assert_equals(angle.unitType, SVGAngle.SVG_ANGLETYPE_UNSPECIFIED);
+
+  assert_throws("SyntaxError", function() { angle.valueAsString = null; });
+  assert_equals(angle.valueAsString, "0");
+  assert_equals(angle.value, 0);
+  assert_equals(angle.valueInSpecifiedUnits, 0);
+  assert_equals(angle.unitType, SVGAngle.SVG_ANGLETYPE_UNSPECIFIED);
+
+  // Check setting invalid 'valueInSpecifiedUnits' arguments
+  assert_throws(new TypeError(), function() { angle.valueInSpecifiedUnits = 'test'; });
+  assert_equals(angle.value, 0);
+  assert_equals(angle.valueInSpecifiedUnits, 0);
+  assert_equals(angle.unitType, SVGAngle.SVG_ANGLETYPE_UNSPECIFIED);
+  angle.valueInSpecifiedUnits = 0;
+  assert_equals(angle.valueInSpecifiedUnits, 0);
+
+  assert_throws(new TypeError(), function() { angle.valueInSpecifiedUnits = angle; });
+  assert_equals(angle.value, 0);
+  assert_throws(new TypeError(), function() { angle.valueInSpecifiedUnits = NaN; });
+  assert_equals(angle.value, 0);
+  assert_throws(new TypeError(), function() { angle.valueInSpecifiedUnits = Infinity; });
+  assert_equals(angle.value, 0);
+  assert_equals(angle.valueInSpecifiedUnits, 0);
+  assert_equals(angle.unitType, SVGAngle.SVG_ANGLETYPE_UNSPECIFIED);
+
+  // Check setting invalid 'value' arguments.
+  angle.value = 0;
+  assert_equals(angle.value, 0);
+  assert_throws(new TypeError(), function() { angle.value = 'test'; });
+  assert_equals(angle.value, 0);
+  assert_equals(angle.valueInSpecifiedUnits, 0);
+  assert_equals(angle.unitType, SVGAngle.SVG_ANGLETYPE_UNSPECIFIED);
+
+  angle.value = 0;
+  assert_equals(angle.value, 0);
+  assert_throws(new TypeError(), function() { angle.value = angle; });
+  assert_equals(angle.value, 0);
+  assert_throws(new TypeError(), function() { angle.value = NaN; });
+  assert_equals(angle.value, 0);
+  assert_throws(new TypeError(), function() { angle.value = Infinity; });
+  assert_equals(angle.value, 0);
+  assert_equals(angle.valueInSpecifiedUnits, 0);
+  assert_equals(angle.unitType, SVGAngle.SVG_ANGLETYPE_UNSPECIFIED);
+
+  // Reset to angle in degree units.
+  angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_DEG, 0);
+  assert_equals(angle.unitType, SVGAngle.SVG_ANGLETYPE_DEG);
+
+  // Check setting valid 'value' arguments, assure that 'valueInSpecifiedUnits' and 'valueAsString' are synchronized.
+  angle.value = 50;
+  assert_equals(angle.value, 50);
+  assert_equals(angle.valueInSpecifiedUnits, 50);
+  assert_equals(angle.valueAsString, "50deg");
+  assert_equals(angle.unitType, SVGAngle.SVG_ANGLETYPE_DEG);
+
+  // Try modifiying the readonly 'unitType', needs to fail.
+  angle.unitType = SVGAngle.SVG_ANGLETYPE_RAD;
+  assert_equals(angle.unitType, SVGAngle.SVG_ANGLETYPE_DEG);
+
+  // Check setting valid 'valueInSpecifiedUnits' arguments, assure that 'value' and 'valueAsString' are synchronized.
+  angle.valueInSpecifiedUnits = 100;
+  assert_equals(angle.valueInSpecifiedUnits, 100);
+  assert_equals(angle.value, 100);
+  assert_equals(angle.valueAsString, "100deg");
+  assert_equals(angle.unitType, SVGAngle.SVG_ANGLETYPE_DEG);
+
+  // Check setting valid 'valueAsString' arguments, assure that 'value' and 'valueInSpecifiedUnits' are synchronized.
+  angle.valueAsString = '200grad';
+  assert_equals(angle.valueAsString, "200grad");
+  assert_equals(angle.valueInSpecifiedUnits, 200);
+  assert_equals(angle.value.toFixed(1), "180.0");
+  assert_equals(angle.unitType, SVGAngle.SVG_ANGLETYPE_GRAD);
+
+  // Now convert the GRAD value into a RAD value, and assure that all properties have been synchronized.
+  angle.convertToSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_RAD);
+  assert_equals(angle.value.toFixed(1), "180.0");
+  assert_equals(angle.valueInSpecifiedUnits.toFixed(5), Math.PI.toFixed(5));
+  assert_equals(angle.valueAsString, Math.PI.toFixed(5) + "rad");
+  assert_equals(angle.unitType, SVGAngle.SVG_ANGLETYPE_RAD);
+
+  // Now try converting the RAD value into an unknown value, that should fail and throw;
+  assert_throws("NotSupportedError", function() { angle.convertToSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_UNKNOWN); });
+  assert_equals(angle.value.toFixed(1), "180.0");
+  assert_equals(angle.valueInSpecifiedUnits.toFixed(5), Math.PI.toFixed(5));
+  assert_equals(angle.valueAsString, Math.PI.toFixed(5) + "rad");
+  assert_equals(angle.unitType, SVGAngle.SVG_ANGLETYPE_RAD);
+
+  // Now convert the RAD value into a DEG value, and assure that all properties have been synchronized.
+  angle.convertToSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_DEG);
+  assert_equals(angle.value.toFixed(1), "180.0");
+  assert_equals(angle.valueInSpecifiedUnits.toFixed(1), "180.0");
+  assert_equals(angle.valueAsString, "180deg");
+  assert_equals(angle.unitType, SVGAngle.SVG_ANGLETYPE_DEG);
+});
+</script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/svg/dom/SVGMatrix-expected.txt b/third_party/WebKit/LayoutTests/svg/dom/SVGMatrix-expected.txt
deleted file mode 100644
index 132bdf3..0000000
--- a/third_party/WebKit/LayoutTests/svg/dom/SVGMatrix-expected.txt
+++ /dev/null
@@ -1,160 +0,0 @@
-This test checks the SVGMatrix API
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-
-Check initial matrix values
-PASS matrix.a is 1
-PASS matrix.b is 0
-PASS matrix.c is 0
-PASS matrix.d is 1
-PASS matrix.e is 0
-PASS matrix.f is 0
-
-Check assigning matrices
-PASS matrix.a = 2 is 2
-PASS matrix.f = 200 is 200
-
-Check assigning invalid matrices
-PASS matrix.a = matrix is matrix
-PASS matrix.a is NaN
-PASS matrix.a = 0 is 0
-PASS matrix.a = svgElement is svgElement
-PASS matrix.a is NaN
-PASS matrix.a = 0 is 0
-PASS matrix.a = 'aString' is 'aString'
-PASS matrix.a is NaN
-PASS matrix.a = 2 is 2
-PASS matrix.b = matrix is matrix
-PASS matrix.b is NaN
-PASS matrix.b = 0 is 0
-PASS matrix.b = svgElement is svgElement
-PASS matrix.b is NaN
-PASS matrix.b = 0 is 0
-PASS matrix.b = 'aString' is 'aString'
-PASS matrix.b is NaN
-PASS matrix.b = 0 is 0
-PASS matrix.c = matrix is matrix
-PASS matrix.c is NaN
-PASS matrix.c = 0 is 0
-PASS matrix.c = svgElement is svgElement
-PASS matrix.c is NaN
-PASS matrix.c = 0 is 0
-PASS matrix.c = 'aString' is 'aString'
-PASS matrix.c is NaN
-PASS matrix.c = 0 is 0
-PASS matrix.d = matrix is matrix
-PASS matrix.d is NaN
-PASS matrix.d = 0 is 0
-PASS matrix.d = svgElement is svgElement
-PASS matrix.d is NaN
-PASS matrix.d = 0 is 0
-PASS matrix.d = 'aString' is 'aString'
-PASS matrix.d is NaN
-PASS matrix.d = 1 is 1
-PASS matrix.e = matrix is matrix
-PASS matrix.e is NaN
-PASS matrix.e = 0 is 0
-PASS matrix.e = svgElement is svgElement
-PASS matrix.e is NaN
-PASS matrix.e = 0 is 0
-PASS matrix.e = 'aString' is 'aString'
-PASS matrix.e is NaN
-PASS matrix.e = 0 is 0
-PASS matrix.f = matrix is matrix
-PASS matrix.f is NaN
-PASS matrix.f = 0 is 0
-PASS matrix.f = svgElement is svgElement
-PASS matrix.f is NaN
-PASS matrix.f = 0 is 0
-PASS matrix.f = 'aString' is 'aString'
-PASS matrix.f is NaN
-PASS matrix.f = 200 is 200
-
-Check that the matrix is still containing the correct values
-PASS matrix.a is 2
-PASS matrix.b is 0
-PASS matrix.c is 0
-PASS matrix.d is 1
-PASS matrix.e is 0
-PASS matrix.f is 200
-
-Check assigning null works as expected
-PASS matrix.f = null is null
-PASS matrix.a is 2
-PASS matrix.b is 0
-PASS matrix.c is 0
-PASS matrix.d is 1
-PASS matrix.e is 0
-PASS matrix.f is 0
-
-Check calling 'multiply' with invalid arguments
-PASS matrix.multiply() threw exception TypeError: Failed to execute 'multiply' on 'SVGMatrix': 1 argument required, but only 0 present..
-PASS matrix.multiply(true) threw exception TypeError: Failed to execute 'multiply' on 'SVGMatrix': parameter 1 is not of type 'SVGMatrix'..
-PASS matrix.multiply(2) threw exception TypeError: Failed to execute 'multiply' on 'SVGMatrix': parameter 1 is not of type 'SVGMatrix'..
-PASS matrix.multiply('aString') threw exception TypeError: Failed to execute 'multiply' on 'SVGMatrix': parameter 1 is not of type 'SVGMatrix'..
-PASS matrix.multiply(svgElement) threw exception TypeError: Failed to execute 'multiply' on 'SVGMatrix': parameter 1 is not of type 'SVGMatrix'..
-
-Check calling 'translate' with invalid arguments
-PASS matrix.translate() threw exception TypeError: Failed to execute 'translate' on 'SVGMatrix': 2 arguments required, but only 0 present..
-PASS matrix.translate(true) threw exception TypeError: Failed to execute 'translate' on 'SVGMatrix': 2 arguments required, but only 1 present..
-PASS matrix.translate(2) threw exception TypeError: Failed to execute 'translate' on 'SVGMatrix': 2 arguments required, but only 1 present..
-PASS matrix.translate('aString') threw exception TypeError: Failed to execute 'translate' on 'SVGMatrix': 2 arguments required, but only 1 present..
-PASS matrix.translate(svgElement) threw exception TypeError: Failed to execute 'translate' on 'SVGMatrix': 2 arguments required, but only 1 present..
-PASS matrix.translate('aString', 'aString') is non-null.
-PASS matrix.translate(svgElement, svgElement) is non-null.
-PASS matrix.translate(2, 'aString') is non-null.
-PASS matrix.translate(2, svgElement) is non-null.
-PASS matrix.translate('aString', 2) is non-null.
-PASS matrix.translate(svgElement, 2) is non-null.
-
-Check calling 'scale' with invalid arguments
-PASS matrix.scale() threw exception TypeError: Failed to execute 'scale' on 'SVGMatrix': 1 argument required, but only 0 present..
-PASS matrix.scale('aString') is non-null.
-PASS matrix.scale(svgElement) is non-null.
-
-Check calling 'scaleNonUniform' with invalid arguments
-PASS matrix.scaleNonUniform() threw exception TypeError: Failed to execute 'scaleNonUniform' on 'SVGMatrix': 2 arguments required, but only 0 present..
-PASS matrix.scaleNonUniform(true) threw exception TypeError: Failed to execute 'scaleNonUniform' on 'SVGMatrix': 2 arguments required, but only 1 present..
-PASS matrix.scaleNonUniform(2) threw exception TypeError: Failed to execute 'scaleNonUniform' on 'SVGMatrix': 2 arguments required, but only 1 present..
-PASS matrix.scaleNonUniform('aString') threw exception TypeError: Failed to execute 'scaleNonUniform' on 'SVGMatrix': 2 arguments required, but only 1 present..
-PASS matrix.scaleNonUniform(svgElement) threw exception TypeError: Failed to execute 'scaleNonUniform' on 'SVGMatrix': 2 arguments required, but only 1 present..
-PASS matrix.scaleNonUniform('aString', 'aString') is non-null.
-PASS matrix.scaleNonUniform(svgElement, svgElement) is non-null.
-PASS matrix.scaleNonUniform(2, 'aString') is non-null.
-PASS matrix.scaleNonUniform(2, svgElement) is non-null.
-PASS matrix.scaleNonUniform('aString', 2) is non-null.
-PASS matrix.scaleNonUniform(svgElement, 2) is non-null.
-
-Check calling 'rotate' with invalid arguments
-PASS matrix.rotate() threw exception TypeError: Failed to execute 'rotate' on 'SVGMatrix': 1 argument required, but only 0 present..
-PASS matrix.rotate('aString') is non-null.
-PASS matrix.rotate(svgElement) is non-null.
-
-Check calling 'rotateFromVector' with invalid arguments
-PASS matrix.rotateFromVector() threw exception TypeError: Failed to execute 'rotateFromVector' on 'SVGMatrix': 2 arguments required, but only 0 present..
-PASS matrix.rotateFromVector(true) threw exception TypeError: Failed to execute 'rotateFromVector' on 'SVGMatrix': 2 arguments required, but only 1 present..
-PASS matrix.rotateFromVector(2) threw exception TypeError: Failed to execute 'rotateFromVector' on 'SVGMatrix': 2 arguments required, but only 1 present..
-PASS matrix.rotateFromVector('aString') threw exception TypeError: Failed to execute 'rotateFromVector' on 'SVGMatrix': 2 arguments required, but only 1 present..
-PASS matrix.rotateFromVector(svgElement) threw exception TypeError: Failed to execute 'rotateFromVector' on 'SVGMatrix': 2 arguments required, but only 1 present..
-PASS matrix.rotateFromVector('aString', 'aString') is non-null.
-PASS matrix.rotateFromVector(svgElement, svgElement) is non-null.
-PASS matrix.rotateFromVector(2, 'aString') is non-null.
-PASS matrix.rotateFromVector(2, svgElement) is non-null.
-PASS matrix.rotateFromVector('aString', 2) is non-null.
-PASS matrix.rotateFromVector(svgElement, 2) is non-null.
-
-Check calling 'skewX' with invalid arguments
-PASS matrix.skewX() threw exception TypeError: Failed to execute 'skewX' on 'SVGMatrix': 1 argument required, but only 0 present..
-PASS matrix.skewX('aString') is non-null.
-PASS matrix.skewX(svgElement) is non-null.
-
-Check calling 'skewY' with invalid arguments
-PASS matrix.skewY() threw exception TypeError: Failed to execute 'skewY' on 'SVGMatrix': 1 argument required, but only 0 present..
-PASS matrix.skewY('aString') is non-null.
-PASS matrix.skewY(svgElement) is non-null.
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/WebKit/LayoutTests/svg/dom/SVGMatrix.html b/third_party/WebKit/LayoutTests/svg/dom/SVGMatrix.html
index a413232..1a7d5ac 100644
--- a/third_party/WebKit/LayoutTests/svg/dom/SVGMatrix.html
+++ b/third_party/WebKit/LayoutTests/svg/dom/SVGMatrix.html
@@ -1,11 +1,156 @@
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<html>
-<head>
-<script src="../../resources/js-test.js"></script>
-</head>
-<body>
-<p id="description"></p>
-<div id="console"></div>
-<script src="script-tests/SVGMatrix.js"></script>
-</body>
-</html>
+<!DOCTYPE HTML>
+<title>SVGMatrix interface</title>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script>
+var svgElement = document.createElementNS("http://www.w3.org/2000/svg", "svg");
+
+function assert_matrix_component_numeric(matrix, component) {
+  matrix[component] = matrix;
+  assert_equals(matrix[component], NaN);
+  matrix[component] = 0;
+  assert_equals(matrix[component], 0);
+  matrix[component] = svgElement;
+  assert_equals(matrix[component], NaN);
+  matrix[component] = 0;
+  assert_equals(matrix[component], 0);
+  matrix[component] = 'aString';
+  assert_equals(matrix[component], NaN);
+}
+
+test(function() {
+  // This test checks the SVGMatrix API.
+  var matrix = svgElement.createSVGMatrix();
+
+  // Check initial matrix values.
+  assert_equals(matrix.a, 1);
+  assert_equals(matrix.b, 0);
+  assert_equals(matrix.c, 0);
+  assert_equals(matrix.d, 1);
+  assert_equals(matrix.e, 0);
+  assert_equals(matrix.f, 0);
+
+  // Check assigning matrices.
+  matrix.a = 2;
+  assert_equals(matrix.a, 2);
+  matrix.f = 200;
+  assert_equals(matrix.f, 200);
+
+  // Check assigning invalid matrices.
+  assert_matrix_component_numeric(matrix, 'a');
+  // Reset to previous value.
+  matrix.a = 2;
+  assert_equals(matrix.a, 2);
+
+  assert_matrix_component_numeric(matrix, 'b');
+  // Reset to previous value.
+  matrix.b = 0;
+  assert_equals(matrix.b, 0);
+
+  assert_matrix_component_numeric(matrix, 'c');
+  // Reset to previous value.
+  matrix.c = 0;
+  assert_equals(matrix.c, 0);
+
+  assert_matrix_component_numeric(matrix, 'd');
+  // Reset to previous value.
+  matrix.d = 1;
+  assert_equals(matrix.d, 1);
+
+  assert_matrix_component_numeric(matrix, 'e');
+  // Reset to previous value.
+  matrix.e = 0;
+  assert_equals(matrix.e, 0);
+
+  assert_matrix_component_numeric(matrix, 'f');
+  // Reset to previous value.
+  matrix.f = 200;
+  assert_equals(matrix.f, 200);
+
+  // Check that the matrix is still containing the correct values.
+  assert_equals(matrix.a, 2);
+  assert_equals(matrix.b, 0);
+  assert_equals(matrix.c, 0);
+  assert_equals(matrix.d, 1);
+  assert_equals(matrix.e, 0);
+  assert_equals(matrix.f, 200);
+
+  // Check assigning null works as expected.
+  matrix.f = null;
+  assert_equals(matrix.a, 2);
+  assert_equals(matrix.b, 0);
+  assert_equals(matrix.c, 0);
+  assert_equals(matrix.d, 1);
+  assert_equals(matrix.e, 0);
+  assert_equals(matrix.f, 0);
+
+  // Check calling 'multiply' with invalid arguments.
+  assert_throws(new TypeError(), function() { matrix.multiply(); });
+  assert_throws(new TypeError(), function() { matrix.multiply(true); });
+  assert_throws(new TypeError(), function() { matrix.multiply(2); });
+  assert_throws(new TypeError(), function() { matrix.multiply('aString'); });
+  assert_throws(new TypeError(), function() { matrix.multiply(svgElement); });
+
+  // Check calling 'translate' with invalid arguments.
+  assert_throws(new TypeError(), function() { matrix.translate(); });
+  assert_throws(new TypeError(), function() { matrix.translate(true); });
+  assert_throws(new TypeError(), function() { matrix.translate(2); });
+  assert_throws(new TypeError(), function() { matrix.translate('aString'); });
+  assert_throws(new TypeError(), function() { matrix.translate(svgElement); });
+  // The following string and object arguments convert to NaN
+  // per ECMA-262, 9.3, "ToNumber".
+  assert_not_equals(matrix.translate('aString', 'aString'), null);
+  assert_not_equals(matrix.translate(svgElement, svgElement), null);
+  assert_not_equals(matrix.translate(2, 'aString'), null);
+  assert_not_equals(matrix.translate(2, svgElement), null);
+  assert_not_equals(matrix.translate('aString', 2), null);
+  assert_not_equals(matrix.translate(svgElement, 2), null);
+
+  // Check calling 'scale' with invalid arguments.
+  assert_throws(new TypeError(), function() { matrix.scale(); });
+  assert_not_equals(matrix.scale('aString'), null);
+  assert_not_equals(matrix.scale(svgElement), null);
+
+
+  // Check calling 'scaleNonUniform' with invalid arguments.
+  assert_throws(new TypeError(), function() { matrix.scaleNonUniform(); });
+  assert_throws(new TypeError(), function() { matrix.scaleNonUniform(true); });
+  assert_throws(new TypeError(), function() { matrix.scaleNonUniform(2); });
+  assert_throws(new TypeError(), function() { matrix.scaleNonUniform('aString'); });
+  assert_throws(new TypeError(), function() { matrix.scaleNonUniform(svgElement); });
+  assert_not_equals(matrix.scaleNonUniform('aString', 'aString'), null);
+  assert_not_equals(matrix.scaleNonUniform(svgElement, svgElement), null);
+  assert_not_equals(matrix.scaleNonUniform(2, 'aString'), null);
+  assert_not_equals(matrix.scaleNonUniform(2, svgElement), null);
+  assert_not_equals(matrix.scaleNonUniform('aString', 2), null);
+  assert_not_equals(matrix.scaleNonUniform(svgElement, 2), null);
+
+  // Check calling 'rotate' with invalid arguments.
+  assert_throws(new TypeError(), function() { matrix.rotate(); });
+  assert_not_equals(matrix.rotate('aString'), null);
+  assert_not_equals(matrix.rotate(svgElement), null);
+
+  // Check calling 'rotateFromVector' with invalid arguments.
+  assert_throws(new TypeError(), function() { matrix.rotateFromVector(); });
+  assert_throws(new TypeError(), function() { matrix.rotateFromVector(true); });
+  assert_throws(new TypeError(), function() { matrix.rotateFromVector(2); });
+  assert_throws(new TypeError(), function() { matrix.rotateFromVector('aString'); });
+  assert_throws(new TypeError(), function() { matrix.rotateFromVector(svgElement); });
+  assert_not_equals(matrix.rotateFromVector('aString', 'aString'), null);
+  assert_not_equals(matrix.rotateFromVector(svgElement, svgElement), null);
+  assert_not_equals(matrix.rotateFromVector(2, 'aString'), null);
+  assert_not_equals(matrix.rotateFromVector(2, svgElement), null);
+  assert_not_equals(matrix.rotateFromVector('aString', 2), null);
+  assert_not_equals(matrix.rotateFromVector(svgElement, 2), null);
+
+  // Check calling 'skewX' with invalid arguments.
+  assert_throws(new TypeError(), function() { matrix.skewX(); });
+  assert_not_equals(matrix.skewX('aString'), null);
+  assert_not_equals(matrix.skewX(svgElement), null);
+
+  // Check calling 'skewY' with invalid arguments;
+  assert_throws(new TypeError(), function() { matrix.skewY(); });
+  assert_not_equals(matrix.skewY('aString'), null);
+  assert_not_equals(matrix.skewY(svgElement), null);
+});
+</script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/svg/dom/SVGNumber-expected.txt b/third_party/WebKit/LayoutTests/svg/dom/SVGNumber-expected.txt
deleted file mode 100644
index 7012605..0000000
--- a/third_party/WebKit/LayoutTests/svg/dom/SVGNumber-expected.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-This test checks the SVGNumber API
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-
-Check initial number value
-PASS num.value is 0
-
-Check assigning number
-PASS num.value = 100 is 100
-PASS num.value = -100 is -100
-PASS num.value = 12345678 is 12345678
-PASS num.value = -num.value is -12345678
-
-Check that numbers are static, caching value in a local variable and modifying it, should have no effect
-PASS numRef is 1000
-PASS num.value is -12345678
-
-Check assigning invalid number, number should be 0 afterwards
-PASS num.value = 0 is 0
-PASS num.value = num threw exception TypeError: Failed to set the 'value' property on 'SVGNumber': The provided float value is non-finite..
-PASS num.value = 'aString' threw exception TypeError: Failed to set the 'value' property on 'SVGNumber': The provided float value is non-finite..
-PASS num.value = svgElement threw exception TypeError: Failed to set the 'value' property on 'SVGNumber': The provided float value is non-finite..
-PASS num.value = NaN threw exception TypeError: Failed to set the 'value' property on 'SVGNumber': The provided float value is non-finite..
-PASS num.value = Infinity threw exception TypeError: Failed to set the 'value' property on 'SVGNumber': The provided float value is non-finite..
-PASS num.value is 0
-PASS num.value = null is null
-
-Check that the number is now null
-PASS num.value is 0
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/WebKit/LayoutTests/svg/dom/SVGNumber.html b/third_party/WebKit/LayoutTests/svg/dom/SVGNumber.html
index 1b141b8..66460fed 100644
--- a/third_party/WebKit/LayoutTests/svg/dom/SVGNumber.html
+++ b/third_party/WebKit/LayoutTests/svg/dom/SVGNumber.html
@@ -1,11 +1,44 @@
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<html>
-<head>
-<script src="../../resources/js-test.js"></script>
-</head>
-<body>
-<p id="description"></p>
-<div id="console"></div>
-<script src="script-tests/SVGNumber.js"></script>
-</body>
-</html>
+<!DOCTYPE HTML>
+<title>SVGNumber interface</title>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script>
+test(function() {
+  // This test checks the SVGNumber API.
+
+  var svgElement = document.createElementNS("http://www.w3.org/2000/svg", "svg");
+  var num = svgElement.createSVGNumber();
+
+  // Check initial number value.
+  assert_equals(num.value, 0);
+
+  // Check assigning number.
+  num.value = 100;
+  assert_equals(num.value, 100);
+  num.value = -100;
+  assert_equals(num.value, -100);
+  num.value = 12345678;
+  assert_equals(num.value, 12345678);
+  num.value = -num.value;
+  assert_equals(num.value, -12345678);
+
+  // Check that numbers are static, caching value in a local variable and modifying it, should have no effect.
+  var numRef = num.value;
+  numRef = 1000;
+  assert_equals(numRef, 1000);
+  assert_equals(num.value, -12345678);
+
+  // Check assigning invalid number, number should be 0 afterwards.
+  num.value = 0;
+  assert_equals(num.value, 0);
+  assert_throws(new TypeError(), function() { num.value = num; });
+  assert_throws(new TypeError(), function() { num.value = 'aString'; });
+  assert_throws(new TypeError(), function() { num.value = svgElement; });
+  assert_throws(new TypeError(), function() { num.value = NaN; });
+  assert_throws(new TypeError(), function() { num.value = Infinity; });
+  assert_equals(num.value, 0);
+  num.value = null;
+  // Check that the number is now null.
+  assert_equals(num.value, 0);
+});
+</script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/svg/dom/SVGPoint-expected.txt b/third_party/WebKit/LayoutTests/svg/dom/SVGPoint-expected.txt
deleted file mode 100644
index 74509b0..0000000
--- a/third_party/WebKit/LayoutTests/svg/dom/SVGPoint-expected.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-This test checks the SVGPoint API
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-
-Check initial point values
-PASS point.x is 0
-PASS point.y is 0
-
-Check assigning points
-PASS point.x = 100 is 100
-PASS point.y = 200 is 200
-
-Check assigning invalid points
-PASS point.x = point is point
-PASS point.y = null is null
-
-Check that the point contains the correct values
-PASS point.x is NaN
-PASS point.y is 0
-
-Reset to -50, 100
-
-Check 'matrixTransform' method - multiply with -1,0,0,2,10,10 matrix, should flip x coordinate, multiply y by two and translate each coordinate by 10
-PASS (newPoint = point.matrixTransform(ctm)).toString() is "[object SVGPoint]"
-PASS newPoint.x is 60
-PASS newPoint.y is 210
-
-Check invalid arguments for 'matrixTransform'
-PASS point.matrixTransform() threw exception TypeError: Failed to execute 'matrixTransform' on 'SVGPoint': 1 argument required, but only 0 present..
-PASS point.matrixTransform(-1) threw exception TypeError: Failed to execute 'matrixTransform' on 'SVGPoint': parameter 1 is not of type 'SVGMatrix'..
-PASS point.matrixTransform(5) threw exception TypeError: Failed to execute 'matrixTransform' on 'SVGPoint': parameter 1 is not of type 'SVGMatrix'..
-PASS point.matrixTransform('aString') threw exception TypeError: Failed to execute 'matrixTransform' on 'SVGPoint': parameter 1 is not of type 'SVGMatrix'..
-PASS point.matrixTransform(point) threw exception TypeError: Failed to execute 'matrixTransform' on 'SVGPoint': parameter 1 is not of type 'SVGMatrix'..
-PASS point.matrixTransform(svgElement) threw exception TypeError: Failed to execute 'matrixTransform' on 'SVGPoint': parameter 1 is not of type 'SVGMatrix'..
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/WebKit/LayoutTests/svg/dom/SVGPoint.html b/third_party/WebKit/LayoutTests/svg/dom/SVGPoint.html
index da53ea0..8cac819 100644
--- a/third_party/WebKit/LayoutTests/svg/dom/SVGPoint.html
+++ b/third_party/WebKit/LayoutTests/svg/dom/SVGPoint.html
@@ -1,11 +1,51 @@
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<html>
-<head>
-<script src="../../resources/js-test.js"></script>
-</head>
-<body>
-<p id="description"></p>
-<div id="console"></div>
-<script src="script-tests/SVGPoint.js"></script>
-</body>
-</html>
+<!DOCTYPE HTML>
+<title>SVGPoint interface</title>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script>
+test(function() {
+  // This test checks the SVGPoint API.
+
+  var svgElement = document.createElementNS("http://www.w3.org/2000/svg", "svg");
+  var point = svgElement.createSVGPoint();
+
+  // Check initial point values.
+  assert_equals(point.x, 0);
+  assert_equals(point.y, 0);
+
+  // Check assigning points.
+  point.x = 100;
+  assert_equals(point.x, 100);
+  point.y = 200;
+  assert_equals(point.y, 200);
+
+  // Check assigning invalid points.
+  point.x = point;
+  assert_equals(point.x, NaN);
+  point.y = null;
+  assert_equals(point.y, 0);
+
+  // Reset to -50, 100
+  point.x = -50;
+  point.y = 100;
+
+  // Check 'matrixTransform' method - multiply with -1,0,0,2,10,10 matrix, should flip x coordinate, multiply y by two and translate each coordinate by 10.
+  var ctm = svgElement.createSVGMatrix();
+  ctm.a = -1;
+  ctm.d = 2;
+  ctm.e = 10;
+  ctm.f = 10;
+  newPoint = point.matrixTransform(ctm);
+  assert_true(newPoint instanceof SVGPoint);
+  assert_equals(newPoint.x, 60);
+  assert_equals(newPoint.y, 210);
+
+  // Check invalid arguments for 'matrixTransform'.
+  assert_throws(new TypeError(), function() { point.matrixTransform(); });
+  assert_throws(new TypeError(), function() { point.matrixTransform(-1); });
+  assert_throws(new TypeError(), function() { point.matrixTransform(5); });
+  assert_throws(new TypeError(), function() { point.matrixTransform('aString'); });
+  assert_throws(new TypeError(), function() { point.matrixTransform(point); });
+  assert_throws(new TypeError(), function() { point.matrixTransform(svgElement); });
+});
+</script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/svg/dom/script-tests/SVGAngle.js b/third_party/WebKit/LayoutTests/svg/dom/script-tests/SVGAngle.js
deleted file mode 100644
index 9d4571c..0000000
--- a/third_party/WebKit/LayoutTests/svg/dom/script-tests/SVGAngle.js
+++ /dev/null
@@ -1,244 +0,0 @@
-description("This test checks the SVGAngle API");
-
-var svgElement = document.createElementNS("http://www.w3.org/2000/svg", "svg");
-var angle = svgElement.createSVGAngle();
-
-debug("");
-debug("Check initial angle values");
-shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_UNSPECIFIED");
-shouldBeEqualToString("angle.valueAsString", "0");
-shouldBe("angle.value", "0");
-shouldBe("angle.valueInSpecifiedUnits", "0");
-
-// Spec: Raised if unitType is SVG_ANGLETYPE_UNKNOWN or not a valid unit type constant (one of the other SVG_ANGLETYPE_* constants defined on this interface).
-debug("");
-debug("Check invalid arguments for 'convertToSpecifiedUnits'");
-shouldThrow("angle.convertToSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_UNKNOWN)");
-shouldThrow("angle.convertToSpecifiedUnits(-1)");
-shouldThrow("angle.convertToSpecifiedUnits(5)");
-// 'aString' converts to short 0 (through NaN) according to ECMA-262, ToUint16.
-// Therefore this throws NOT_SUPPORTED_ERR.
-shouldThrow("angle.convertToSpecifiedUnits('aString')");
-// Same here, via ToString conversion of object.
-shouldThrow("angle.convertToSpecifiedUnits(angle)");
-// Same here, via ToString conversion of object.
-shouldThrow("angle.convertToSpecifiedUnits(svgElement)");
-shouldThrow("angle.convertToSpecifiedUnits()");
-shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_UNSPECIFIED");
-
-debug("");
-debug("Check valid arguments for 'convertToSpecifiedUnits', that should only modify the 'valueAsString'");
-shouldBeUndefined("angle.convertToSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_RAD)");
-shouldBeEqualToString("angle.valueAsString", "0rad");
-shouldBe("angle.value", "0");
-shouldBe("angle.valueInSpecifiedUnits", "0");
-shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_RAD");
-
-shouldBeUndefined("angle.convertToSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_GRAD)");
-shouldBeEqualToString("angle.valueAsString", "0grad");
-shouldBe("angle.value", "0");
-shouldBe("angle.valueInSpecifiedUnits", "0");
-shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_GRAD");
-
-shouldBeUndefined("angle.convertToSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_DEG)");
-shouldBeEqualToString("angle.valueAsString", "0deg");
-shouldBe("angle.value", "0");
-shouldBe("angle.valueInSpecifiedUnits", "0");
-shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_DEG");
-
-shouldBeUndefined("angle.convertToSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_UNSPECIFIED)");
-shouldBeEqualToString("angle.valueAsString", "0");
-shouldBe("angle.value", "0");
-shouldBe("angle.valueInSpecifiedUnits", "0");
-shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_UNSPECIFIED");
-
-// Spec: Raised if unitType is SVG_ANGLETYPE_UNKNOWN or not a valid unit type constant (one of the other SVG_ANGLETYPE_* constants defined on this interface).
-debug("");
-debug("Check invalid arguments for 'newValueSpecifiedUnits'");
-shouldThrow("angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_UNKNOWN, 50)");
-shouldThrow("angle.newValueSpecifiedUnits(-1, 50)");
-shouldThrow("angle.newValueSpecifiedUnits(5, 50)");
-shouldThrow("angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_DEG)");
-shouldThrow("angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_DEG, 'aString')");
-shouldBe("angle.value", "0");
-shouldBeUndefined("angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_DEG, 0)");
-shouldThrow("angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_DEG, angle)");
-shouldBe("angle.value", "0");
-shouldThrow("angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_DEG, svgElement)");
-shouldBe("angle.value", "0");
-shouldThrow("angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_DEG, NaN)");
-shouldBe("angle.value", "0");
-shouldThrow("angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_DEG, Infinity)");
-shouldBe("angle.value", "0");
-shouldThrow("angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_DEG)");
-// All of the following unitType arguments convert to 0 (SVG_ANGLETYPE_UNKNOWN).
-shouldThrow("angle.newValueSpecifiedUnits('aString', 4)");
-shouldThrow("angle.newValueSpecifiedUnits(angle, 4)");
-shouldThrow("angle.newValueSpecifiedUnits(svgElement, 4)");
-shouldThrow("angle.newValueSpecifiedUnits('aString', 'aString')");
-shouldThrow("angle.newValueSpecifiedUnits(angle, angle)");
-shouldThrow("angle.newValueSpecifiedUnits(svgElement, svgElement)");
-shouldThrow("angle.newValueSpecifiedUnits()");
-shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_DEG");
-
-debug("");
-debug("Check valid arguments for 'newValueSpecifiedUnits', that should only modify the 'valueAsString'");
-shouldBeUndefined("angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_RAD, parseFloat(Math.PI.toFixed(5)))");
-shouldBeEqualToString("angle.valueAsString", Math.PI.toFixed(5) + "rad");
-shouldBeEqualToString("angle.value.toFixed(1)", "180.0");
-shouldBe("angle.valueInSpecifiedUnits.toFixed(5)", "Math.PI.toFixed(5)");
-shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_RAD");
-
-shouldBeUndefined("angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_GRAD, 400)");
-shouldBeEqualToString("angle.valueAsString", "400grad");
-shouldBeEqualToString("angle.value.toFixed(1)", "360.0");
-shouldBe("angle.valueInSpecifiedUnits", "400");
-shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_GRAD");
-
-shouldBeUndefined("angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_DEG, 360)");
-shouldBeEqualToString("angle.valueAsString", "360deg");
-shouldBe("angle.value", "360");
-shouldBe("angle.valueInSpecifiedUnits", "360");
-shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_DEG");
-
-shouldBeUndefined("angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_UNSPECIFIED, 180)");
-shouldBeEqualToString("angle.valueAsString", "180");
-shouldBe("angle.value", "180");
-shouldBe("angle.valueInSpecifiedUnits", "180");
-shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_UNSPECIFIED");
-
-debug("");
-debug("Reset to initial angle state");
-shouldBeUndefined("angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_UNSPECIFIED, 0)");
-shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_UNSPECIFIED");
-
-// Spec: Raised if the assigned string cannot be parsed as a valid <angle>.
-debug("");
-debug("Check setting invalid 'valueAsString' arguments");
-shouldThrow("angle.valueAsString = '10px'");
-shouldBeEqualToString("angle.valueAsString", "0");
-shouldBe("angle.value", "0");
-shouldBe("angle.valueInSpecifiedUnits", "0");
-shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_UNSPECIFIED");
-
-shouldThrow("angle.valueAsString = '10x'");
-shouldBeEqualToString("angle.valueAsString", "0");
-shouldBe("angle.value", "0");
-shouldBe("angle.valueInSpecifiedUnits", "0");
-shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_UNSPECIFIED");
-
-shouldThrow("angle.valueAsString = '5graD'");
-shouldBeEqualToString("angle.valueAsString", "0");
-shouldBe("angle.value", "0");
-shouldBe("angle.valueInSpecifiedUnits", "0");
-shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_UNSPECIFIED");
-
-shouldThrow("angle.valueAsString = '5Rad'");
-shouldBeEqualToString("angle.valueAsString", "0");
-shouldBe("angle.value", "0");
-shouldBe("angle.valueInSpecifiedUnits", "0");
-shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_UNSPECIFIED");
-
-shouldThrow("angle.valueAsString = ',5 rad'");
-shouldBeEqualToString("angle.valueAsString", "0");
-shouldBe("angle.value", "0");
-shouldBe("angle.valueInSpecifiedUnits", "0");
-shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_UNSPECIFIED");
-
-shouldThrow("angle.valueAsString = null");
-shouldBeEqualToString("angle.valueAsString", "0");
-shouldBe("angle.value", "0");
-shouldBe("angle.valueInSpecifiedUnits", "0");
-shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_UNSPECIFIED");
-
-debug("");
-debug("Check setting invalid 'valueInSpecifiedUnits' arguments");
-shouldThrow("angle.valueInSpecifiedUnits = 'test'");
-shouldBe("angle.value", "0");
-shouldBe("angle.valueInSpecifiedUnits", "0");
-shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_UNSPECIFIED");
-shouldBe("angle.valueInSpecifiedUnits = 0", "0");
-
-shouldThrow("angle.valueInSpecifiedUnits = angle");
-shouldBe("angle.value", "0");
-shouldThrow("angle.valueInSpecifiedUnits = NaN");
-shouldBe("angle.value", "0");
-shouldThrow("angle.valueInSpecifiedUnits = Infinity");
-shouldBe("angle.value", "0");
-shouldBe("angle.valueInSpecifiedUnits", "0");
-shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_UNSPECIFIED");
-
-debug("");
-debug("Check setting invalid 'value' arguments");
-shouldBe("angle.value = 0", "0");
-shouldThrow("angle.value = 'test'");
-shouldBe("angle.value", "0");
-shouldBe("angle.valueInSpecifiedUnits", "0");
-shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_UNSPECIFIED");
-
-shouldBe("angle.value = 0", "0");
-shouldThrow("angle.value = angle");
-shouldBe("angle.value", "0");
-shouldThrow("angle.value = NaN");
-shouldBe("angle.value", "0");
-shouldThrow("angle.value = Infinity");
-shouldBe("angle.value", "0");
-shouldBe("angle.valueInSpecifiedUnits", "0");
-shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_UNSPECIFIED");
-
-debug("");
-debug("Reset to angle in degree units");
-shouldBeUndefined("angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_DEG, 0)");
-shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_DEG");
-
-debug("");
-debug("Check setting valid 'value' arguments, assure that 'valueInSpecifiedUnits' and 'valueAsString' are synchronized");
-shouldBe("angle.value = 50", "50");
-shouldBe("angle.valueInSpecifiedUnits", "50");
-shouldBeEqualToString("angle.valueAsString", "50deg");
-shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_DEG");
-
-debug("");
-debug("Try modifiying the readonly 'unitType', needs to fail");
-shouldBeUndefined("angle.unitType = SVGAngle.SVG_ANGLETTYE_RAD");
-shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_DEG");
-
-debug("");
-debug("Check setting valid 'valueInSpecifiedUnits' arguments, assure that 'value' and 'valueAsString' are synchronized");
-shouldBe("angle.valueInSpecifiedUnits = 100", "100");
-shouldBe("angle.value", "100");
-shouldBeEqualToString("angle.valueAsString", "100deg");
-shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_DEG");
-
-debug("");
-debug("Check setting valid 'valueAsString' arguments, assure that 'value' and 'valueInSpecifiedUnits' are synchronized");
-shouldBeEqualToString("angle.valueAsString = '200grad'", "200grad");
-shouldBe("angle.valueInSpecifiedUnits", "200");
-shouldBeEqualToString("angle.value.toFixed(1)", "180.0");
-shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_GRAD");
-
-debug("");
-debug("Now convert the GRAD value into a RAD value, and assure that all properties have been synchronized");
-shouldBeUndefined("angle.convertToSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_RAD)");
-shouldBeEqualToString("angle.value.toFixed(1)", "180.0");
-shouldBeEqualToString("angle.valueInSpecifiedUnits.toFixed(5)", Math.PI.toFixed(5));
-shouldBeEqualToString("angle.valueAsString", Math.PI.toFixed(5) + "rad");
-shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_RAD");
-
-debug("");
-debug("Now try converting the RAD value into an unknown value, that should fail and throw");
-shouldThrow("angle.convertToSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_UNKNOWN)");
-shouldBeEqualToString("angle.value.toFixed(1)", "180.0");
-shouldBeEqualToString("angle.valueInSpecifiedUnits.toFixed(5)", Math.PI.toFixed(5));
-shouldBeEqualToString("angle.valueAsString", Math.PI.toFixed(5) + "rad");
-shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_RAD");
-
-debug("");
-debug("Now convert the RAD value into a DEG value, and assure that all properties have been synchronized");
-shouldBeUndefined("angle.convertToSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_DEG)");
-shouldBeEqualToString("angle.value.toFixed(1)", "180.0");
-shouldBeEqualToString("angle.valueInSpecifiedUnits.toFixed(1)", "180.0");
-shouldBeEqualToString("angle.valueAsString", "180deg");
-shouldBe("angle.unitType", "SVGAngle.SVG_ANGLETYPE_DEG");
-
-successfullyParsed = true;
diff --git a/third_party/WebKit/LayoutTests/svg/dom/script-tests/SVGMatrix.js b/third_party/WebKit/LayoutTests/svg/dom/script-tests/SVGMatrix.js
deleted file mode 100644
index 017ae5a8..0000000
--- a/third_party/WebKit/LayoutTests/svg/dom/script-tests/SVGMatrix.js
+++ /dev/null
@@ -1,184 +0,0 @@
-description("This test checks the SVGMatrix API");
-
-var svgElement = document.createElementNS("http://www.w3.org/2000/svg", "svg");
-var matrix = svgElement.createSVGMatrix();
-
-debug("");
-debug("Check initial matrix values");
-shouldBe("matrix.a", "1");
-shouldBe("matrix.b", "0");
-shouldBe("matrix.c", "0");
-shouldBe("matrix.d", "1");
-shouldBe("matrix.e", "0");
-shouldBe("matrix.f", "0");
-
-debug("");
-debug("Check assigning matrices");
-shouldBe("matrix.a = 2", "2");
-shouldBe("matrix.f = 200", "200");
-
-debug("");
-debug("Check assigning invalid matrices");
-shouldBe("matrix.a = matrix", "matrix");
-shouldBe("matrix.a", "NaN");
-shouldBe("matrix.a = 0", "0");
-shouldBe("matrix.a = svgElement", "svgElement");
-shouldBe("matrix.a", "NaN");
-shouldBe("matrix.a = 0", "0");
-shouldBe("matrix.a = 'aString'", "'aString'");
-shouldBe("matrix.a", "NaN");
-// Reset to previous value.
-shouldBe("matrix.a = 2", "2");
-
-shouldBe("matrix.b = matrix", "matrix");
-shouldBe("matrix.b", "NaN");
-shouldBe("matrix.b = 0", "0");
-shouldBe("matrix.b = svgElement", "svgElement");
-shouldBe("matrix.b", "NaN");
-shouldBe("matrix.b = 0", "0");
-shouldBe("matrix.b = 'aString'", "'aString'");
-shouldBe("matrix.b", "NaN");
-// Reset to previous value.
-shouldBe("matrix.b = 0", "0");
-
-shouldBe("matrix.c = matrix", "matrix");
-shouldBe("matrix.c", "NaN");
-shouldBe("matrix.c = 0", "0");
-shouldBe("matrix.c = svgElement", "svgElement");
-shouldBe("matrix.c", "NaN");
-shouldBe("matrix.c = 0", "0");
-shouldBe("matrix.c = 'aString'", "'aString'");
-shouldBe("matrix.c", "NaN");
-// Reset to previous value.
-shouldBe("matrix.c = 0", "0");
-
-shouldBe("matrix.d = matrix", "matrix");
-shouldBe("matrix.d", "NaN");
-shouldBe("matrix.d = 0", "0");
-shouldBe("matrix.d = svgElement", "svgElement");
-shouldBe("matrix.d", "NaN");
-shouldBe("matrix.d = 0", "0");
-shouldBe("matrix.d = 'aString'", "'aString'");
-shouldBe("matrix.d", "NaN");
-// Reset to previous value.
-shouldBe("matrix.d = 1", "1");
-
-shouldBe("matrix.e = matrix", "matrix");
-shouldBe("matrix.e", "NaN");
-shouldBe("matrix.e = 0", "0");
-shouldBe("matrix.e = svgElement", "svgElement");
-shouldBe("matrix.e", "NaN");
-shouldBe("matrix.e = 0", "0");
-shouldBe("matrix.e = 'aString'", "'aString'");
-shouldBe("matrix.e", "NaN");
-// Reset to previous value.
-shouldBe("matrix.e = 0", "0");
-
-shouldBe("matrix.f = matrix", "matrix");
-shouldBe("matrix.f", "NaN");
-shouldBe("matrix.f = 0", "0");
-shouldBe("matrix.f = svgElement", "svgElement");
-shouldBe("matrix.f", "NaN");
-shouldBe("matrix.f = 0", "0");
-shouldBe("matrix.f = 'aString'", "'aString'");
-shouldBe("matrix.f", "NaN");
-// Reset to previous value.
-shouldBe("matrix.f = 200", "200");
-
-debug("");
-debug("Check that the matrix is still containing the correct values");
-shouldBe("matrix.a", "2");
-shouldBe("matrix.b", "0");
-shouldBe("matrix.c", "0");
-shouldBe("matrix.d", "1");
-shouldBe("matrix.e", "0");
-shouldBe("matrix.f", "200");
-
-debug("");
-debug("Check assigning null works as expected");
-shouldBeNull("matrix.f = null");
-shouldBe("matrix.a", "2");
-shouldBe("matrix.b", "0");
-shouldBe("matrix.c", "0");
-shouldBe("matrix.d", "1");
-shouldBe("matrix.e", "0");
-shouldBe("matrix.f", "0");
-
-debug("");
-debug("Check calling 'multiply' with invalid arguments");
-shouldThrow("matrix.multiply()");
-shouldThrow("matrix.multiply(true)");
-shouldThrow("matrix.multiply(2)");
-shouldThrow("matrix.multiply('aString')");
-shouldThrow("matrix.multiply(svgElement)");
-
-debug("");
-debug("Check calling 'translate' with invalid arguments");
-shouldThrow("matrix.translate()");
-shouldThrow("matrix.translate(true)");
-shouldThrow("matrix.translate(2)");
-shouldThrow("matrix.translate('aString')");
-shouldThrow("matrix.translate(svgElement)");
-// The following string and object arguments convert to NaN
-// per ECMA-262, 9.3, "ToNumber".
-shouldBeNonNull("matrix.translate('aString', 'aString')");
-shouldBeNonNull("matrix.translate(svgElement, svgElement)");
-shouldBeNonNull("matrix.translate(2, 'aString')");
-shouldBeNonNull("matrix.translate(2, svgElement)");
-shouldBeNonNull("matrix.translate('aString', 2)");
-shouldBeNonNull("matrix.translate(svgElement, 2)");
-
-debug("");
-debug("Check calling 'scale' with invalid arguments");
-shouldThrow("matrix.scale()");
-shouldBeNonNull("matrix.scale('aString')");
-shouldBeNonNull("matrix.scale(svgElement)");
-
-
-debug("");
-debug("Check calling 'scaleNonUniform' with invalid arguments");
-shouldThrow("matrix.scaleNonUniform()");
-shouldThrow("matrix.scaleNonUniform(true)");
-shouldThrow("matrix.scaleNonUniform(2)");
-shouldThrow("matrix.scaleNonUniform('aString')");
-shouldThrow("matrix.scaleNonUniform(svgElement)");
-shouldBeNonNull("matrix.scaleNonUniform('aString', 'aString')");
-shouldBeNonNull("matrix.scaleNonUniform(svgElement, svgElement)");
-shouldBeNonNull("matrix.scaleNonUniform(2, 'aString')");
-shouldBeNonNull("matrix.scaleNonUniform(2, svgElement)");
-shouldBeNonNull("matrix.scaleNonUniform('aString', 2)");
-shouldBeNonNull("matrix.scaleNonUniform(svgElement, 2)");
-
-debug("");
-debug("Check calling 'rotate' with invalid arguments");
-shouldThrow("matrix.rotate()");
-shouldBeNonNull("matrix.rotate('aString')");
-shouldBeNonNull("matrix.rotate(svgElement)");
-
-debug("");
-debug("Check calling 'rotateFromVector' with invalid arguments");
-shouldThrow("matrix.rotateFromVector()");
-shouldThrow("matrix.rotateFromVector(true)");
-shouldThrow("matrix.rotateFromVector(2)");
-shouldThrow("matrix.rotateFromVector('aString')");
-shouldThrow("matrix.rotateFromVector(svgElement)");
-shouldBeNonNull("matrix.rotateFromVector('aString', 'aString')");
-shouldBeNonNull("matrix.rotateFromVector(svgElement, svgElement)");
-shouldBeNonNull("matrix.rotateFromVector(2, 'aString')");
-shouldBeNonNull("matrix.rotateFromVector(2, svgElement)");
-shouldBeNonNull("matrix.rotateFromVector('aString', 2)");
-shouldBeNonNull("matrix.rotateFromVector(svgElement, 2)");
-
-debug("");
-debug("Check calling 'skewX' with invalid arguments");
-shouldThrow("matrix.skewX()");
-shouldBeNonNull("matrix.skewX('aString')");
-shouldBeNonNull("matrix.skewX(svgElement)");
-
-debug("");
-debug("Check calling 'skewY' with invalid arguments");
-shouldThrow("matrix.skewY()");
-shouldBeNonNull("matrix.skewY('aString')");
-shouldBeNonNull("matrix.skewY(svgElement)");
-
-successfullyParsed = true;
diff --git a/third_party/WebKit/LayoutTests/svg/dom/script-tests/SVGNumber.js b/third_party/WebKit/LayoutTests/svg/dom/script-tests/SVGNumber.js
deleted file mode 100644
index d728676..0000000
--- a/third_party/WebKit/LayoutTests/svg/dom/script-tests/SVGNumber.js
+++ /dev/null
@@ -1,39 +0,0 @@
-description("This test checks the SVGNumber API");
-
-var svgElement = document.createElementNS("http://www.w3.org/2000/svg", "svg");
-var num = svgElement.createSVGNumber();
-
-debug("");
-debug("Check initial number value");
-shouldBe("num.value", "0");
-
-debug("");
-debug("Check assigning number");
-shouldBe("num.value = 100", "100");
-shouldBe("num.value = -100", "-100");
-shouldBe("num.value = 12345678", "12345678");
-shouldBe("num.value = -num.value", "-12345678");
-
-debug("");
-debug("Check that numbers are static, caching value in a local variable and modifying it, should have no effect");
-var numRef = num.value;
-numRef = 1000;
-shouldBe("numRef", "1000");
-shouldBe("num.value", "-12345678");
-
-debug("");
-debug("Check assigning invalid number, number should be 0 afterwards");
-shouldBe("num.value = 0", "0");
-shouldThrow("num.value = num");
-shouldThrow("num.value = 'aString'");
-shouldThrow("num.value = svgElement");
-shouldThrow("num.value = NaN");
-shouldThrow("num.value = Infinity");
-shouldBe("num.value", "0");
-shouldBeNull("num.value = null");
-
-debug("");
-debug("Check that the number is now null");
-shouldBe("num.value", "0");
-
-successfullyParsed = true;
diff --git a/third_party/WebKit/LayoutTests/svg/dom/script-tests/SVGPoint.js b/third_party/WebKit/LayoutTests/svg/dom/script-tests/SVGPoint.js
deleted file mode 100644
index a9e9c7e5..0000000
--- a/third_party/WebKit/LayoutTests/svg/dom/script-tests/SVGPoint.js
+++ /dev/null
@@ -1,51 +0,0 @@
-description("This test checks the SVGPoint API");
-
-var svgElement = document.createElementNS("http://www.w3.org/2000/svg", "svg");
-var point = svgElement.createSVGPoint();
-
-debug("");
-debug("Check initial point values");
-shouldBe("point.x", "0");
-shouldBe("point.y", "0");
-
-debug("");
-debug("Check assigning points");
-shouldBe("point.x = 100", "100");
-shouldBe("point.y = 200", "200");
-
-debug("");
-debug("Check assigning invalid points");
-shouldBe("point.x = point", "point");
-shouldBeNull("point.y = null");
-
-debug("");
-debug("Check that the point contains the correct values");
-shouldBe("point.x", "NaN");
-shouldBe("point.y", "0");
-
-debug("");
-debug("Reset to -50, 100");
-point.x = -50;
-point.y = 100;
-
-debug("");
-debug("Check 'matrixTransform' method - multiply with -1,0,0,2,10,10 matrix, should flip x coordinate, multiply y by two and translate each coordinate by 10");
-var ctm = svgElement.createSVGMatrix();
-ctm.a = -1;
-ctm.d = 2;
-ctm.e = 10;
-ctm.f = 10;
-shouldBeEqualToString("(newPoint = point.matrixTransform(ctm)).toString()", "[object SVGPoint]");
-shouldBe("newPoint.x", "60");
-shouldBe("newPoint.y", "210");
-
-debug("");
-debug("Check invalid arguments for 'matrixTransform'");
-shouldThrow("point.matrixTransform()");
-shouldThrow("point.matrixTransform(-1)");
-shouldThrow("point.matrixTransform(5)");
-shouldThrow("point.matrixTransform('aString')");
-shouldThrow("point.matrixTransform(point)");
-shouldThrow("point.matrixTransform(svgElement)");
-
-successfullyParsed = true;
diff --git a/third_party/WebKit/LayoutTests/svg/transforms/svgdom-manipulation-before-attach-expected.html b/third_party/WebKit/LayoutTests/svg/transforms/svgdom-manipulation-before-attach-expected.html
new file mode 100644
index 0000000..f718ea6
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/svg/transforms/svgdom-manipulation-before-attach-expected.html
@@ -0,0 +1,2 @@
+<!DOCTYPE html>
+<div style="width: 100px; height: 100px; background-color: green"></div>
diff --git a/third_party/WebKit/LayoutTests/svg/transforms/svgdom-manipulation-before-attach.html b/third_party/WebKit/LayoutTests/svg/transforms/svgdom-manipulation-before-attach.html
new file mode 100644
index 0000000..500442e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/svg/transforms/svgdom-manipulation-before-attach.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<svg></svg>
+<script>
+var svg = document.querySelector("svg");
+var g = document.createElementNS('http://www.w3.org/2000/svg', 'g');
+var rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
+var attrs = { x: 100, y:100, width: 100, height: 100, fill: 'green' };
+for (var k in attrs)
+  rect.setAttribute(k, attrs[k]);
+
+var matrix = svg.createSVGMatrix().translate(-100, -100);
+g.transform.baseVal.appendItem(svg.createSVGTransformFromMatrix(matrix));
+
+svg.appendChild(g).appendChild(rect);
+</script>
diff --git a/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
index b5710626..11a8bbd 100644
--- a/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -432,12 +432,6 @@
     method readAsBinaryString
     method readAsDataURL
     method readAsText
-interface Float32ImageData
-    getter colorSpace
-    getter data
-    getter height
-    getter width
-    method constructor
 interface ForeignFetchEvent : ExtendableEvent
     getter origin
     getter request
@@ -604,8 +598,9 @@
     method close
     method constructor
 interface ImageData
-    getter colorSpace
+    getter colorSettings
     getter data
+    getter dataUnion
     getter height
     getter width
     method constructor
diff --git a/third_party/WebKit/LayoutTests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/WebKit/LayoutTests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
index 041a2cfe..b0de26396 100644
--- a/third_party/WebKit/LayoutTests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -375,7 +375,6 @@
     method close
     method constructor
 interface ImageData
-    getter colorSpace
     getter data
     getter height
     getter width
diff --git a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt
index dbbc460..8340ed2 100644
--- a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt
@@ -396,7 +396,6 @@
 [Worker]     method constructor
 [Worker] interface ImageData
 [Worker]     attribute @@toStringTag
-[Worker]     getter colorSpace
 [Worker]     getter data
 [Worker]     getter height
 [Worker]     getter width
diff --git a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt
index 73ba7bf..8078069 100644
--- a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt
@@ -391,7 +391,6 @@
 [Worker]     method constructor
 [Worker] interface ImageData
 [Worker]     attribute @@toStringTag
-[Worker]     getter colorSpace
 [Worker]     getter data
 [Worker]     getter height
 [Worker]     getter width
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt
index 65bc1ab..08466b37 100644
--- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt
@@ -435,13 +435,6 @@
 [Worker]     method readAsBinaryString
 [Worker]     method readAsDataURL
 [Worker]     method readAsText
-[Worker] interface Float32ImageData
-[Worker]     attribute @@toStringTag
-[Worker]     getter colorSpace
-[Worker]     getter data
-[Worker]     getter height
-[Worker]     getter width
-[Worker]     method constructor
 [Worker] interface FormData
 [Worker]     attribute @@toStringTag
 [Worker]     method @@iterator
@@ -622,8 +615,9 @@
 [Worker]     method constructor
 [Worker] interface ImageData
 [Worker]     attribute @@toStringTag
-[Worker]     getter colorSpace
+[Worker]     getter colorSettings
 [Worker]     getter data
+[Worker]     getter dataUnion
 [Worker]     getter height
 [Worker]     getter width
 [Worker]     method constructor
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
index a0d48ef..00c8d2e 100644
--- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -1889,13 +1889,6 @@
     setter onloadend
     setter onloadstart
     setter onprogress
-interface Float32ImageData
-    attribute @@toStringTag
-    getter colorSpace
-    getter data
-    getter height
-    getter width
-    method constructor
 interface FocusEvent : UIEvent
     attribute @@toStringTag
     getter relatedTarget
@@ -3761,8 +3754,9 @@
     method takePhoto
 interface ImageData
     attribute @@toStringTag
-    getter colorSpace
+    getter colorSettings
     getter data
+    getter dataUnion
     getter height
     getter width
     method constructor
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt
index 9b57ad9..86451564 100644
--- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt
@@ -430,13 +430,6 @@
 [Worker]     method readAsBinaryString
 [Worker]     method readAsDataURL
 [Worker]     method readAsText
-[Worker] interface Float32ImageData
-[Worker]     attribute @@toStringTag
-[Worker]     getter colorSpace
-[Worker]     getter data
-[Worker]     getter height
-[Worker]     getter width
-[Worker]     method constructor
 [Worker] interface FormData
 [Worker]     attribute @@toStringTag
 [Worker]     method @@iterator
@@ -617,8 +610,9 @@
 [Worker]     method constructor
 [Worker] interface ImageData
 [Worker]     attribute @@toStringTag
-[Worker]     getter colorSpace
+[Worker]     getter colorSettings
 [Worker]     getter data
+[Worker]     getter dataUnion
 [Worker]     getter height
 [Worker]     getter width
 [Worker]     method constructor
diff --git a/third_party/WebKit/PerformanceTests/Canvas/getImageDataColorManaged.html b/third_party/WebKit/PerformanceTests/Canvas/getImageDataColorManaged.html
new file mode 100644
index 0000000..c637630
--- /dev/null
+++ b/third_party/WebKit/PerformanceTests/Canvas/getImageDataColorManaged.html
@@ -0,0 +1,93 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src="../resources/runner.js"></script>
+<script>
+
+var dataSize = 4000000;
+var dataU8 = new Uint8ClampedArray(dataSize);
+var dataU16 = new Uint16Array(dataSize);
+var dataF32 = new Float32Array(dataSize);
+
+var imageData;
+var imageDataU8;
+var imageDataU16;
+var imageDataF32;
+
+var accessCount = 1000000;
+var accessLocations = new Uint32Array(accessCount);
+
+function rand(range) {
+    return Math.floor(Math.random() * range);
+}
+
+function fillArrays() {
+    for (i = 0; i < dataSize; i++) {
+        dataU8[i] = rand(256);
+        dataU16[i] = rand(65536);
+        dataF32[i] = rand(1);
+    }
+    for (i = 0; i < accessCount; i++)
+        accessLocations[i] = rand(dataSize);
+}
+
+
+function readArray(array, accessLocations, arrayName) {
+    var sum = 0;
+    for (i = 0; i < accessLocations.length; i++)
+        sum = sum + array[accessLocations[i]];
+    return sum;
+}
+
+function writeArray(array, accessLocations, arrayName) {
+    for (i = 0; i < accessLocations.length; i++)
+        array[accessLocations[i]] = 0;
+}
+
+function ImageData_data_AccessTime() {
+    var experimental = new ImageData(1,1);  
+    imageData = experimental.createImageData(dataU8, 1000, 1000, {colorSpace: "srgb"});
+    readArray(imageData.data, accessLocations);
+    writeArray(imageData.data, accessLocations);
+}
+
+function ImageData_dataUnionU8_AccessTime() {
+    var experimental = new ImageData(1,1);  
+    imageDataU8 = experimental.createImageData(dataU8, 1000, 1000, {colorSpace: "srgb"});
+    readArray(imageDataU8.dataUnion, accessLocations);
+    writeArray(imageDataU8.dataUnion, accessLocations);
+
+}
+
+function ImageData_dataUnionU16_AccessTime() {
+    var experimental = new ImageData(1,1);  
+    imageDataU16 = experimental.createImageData(dataU16, 1000, 1000, {colorSpace: "srgb"});
+    readArray(imageDataU16.dataUnion, accessLocations);
+    writeArray(imageDataU16.dataUnion, accessLocations);
+}
+
+function ImageData_dataUnionF32_AccessTime() {
+    var experimental = new ImageData(1,1);  
+    imageDataF32 = experimental.createImageData(dataF32, 1000, 1000, {colorSpace: "srgb"});
+    readArray(imageDataF32.dataUnion, accessLocations, "imageDataF32.dataUnion");
+    writeArray(imageDataF32.dataUnion, accessLocations, "imageDataF32.dataUnion");
+}
+
+
+PerfTestRunner.measureRunsPerSecond({run: ImageData_data_AccessTime, description: "This bench test checks the speed of reading and writing 250K pixels (equivalent) to ImageData.data."});
+
+PerfTestRunner.measureRunsPerSecond({run: ImageData_dataUnionU8_AccessTime, description: "This bench test checks the speed of reading and writing 250K pixels (equivalent) to ImageData.dataUnion of type Uint8ClampedArray."});
+
+PerfTestRunner.measureRunsPerSecond({run: ImageData_dataUnionU16_AccessTime, description: "This bench test checks the speed of reading and writing 250K pixels (equivalent) to ImageData.dataUnion of type Uin16Array."});
+
+PerfTestRunner.measureRunsPerSecond({run: ImageData_dataUnionF32_AccessTime, description: "This bench test checks the speed of reading and writing 250K pixels (equivalent) to ImageData.dataUnion of type Float32Array."});
+</script>
+</body>
+</html>
+
+
+test(() => {
+  runTest();
+}, "Test ImageData.dataUnion access time");
+</script>
+</body>
diff --git a/third_party/WebKit/Source/bindings/core/v8/BUILD.gn b/third_party/WebKit/Source/bindings/core/v8/BUILD.gn
index 3219d73..cd9dba2 100644
--- a/third_party/WebKit/Source/bindings/core/v8/BUILD.gn
+++ b/third_party/WebKit/Source/bindings/core/v8/BUILD.gn
@@ -121,6 +121,8 @@
   "$blink_core_output_dir/frame/ScrollToOptions.h",
   "$blink_core_output_dir/html/AssignedNodesOptions.cpp",
   "$blink_core_output_dir/html/AssignedNodesOptions.h",
+  "$blink_core_output_dir/html/ImageDataColorSettings.cpp",
+  "$blink_core_output_dir/html/ImageDataColorSettings.h",
   "$blink_core_output_dir/html/canvas/CanvasContextCreationAttributes.cpp",
   "$blink_core_output_dir/html/canvas/CanvasContextCreationAttributes.h",
   "$blink_core_output_dir/html/track/TrackEventInit.cpp",
@@ -228,6 +230,8 @@
   "$bindings_core_v8_output_dir/USVStringSequenceSequenceOrUSVStringOrURLSearchParams.h",
   "$bindings_core_v8_output_dir/UnrestrictedDoubleOrString.cpp",
   "$bindings_core_v8_output_dir/UnrestrictedDoubleOrString.h",
+  "$bindings_core_v8_output_dir/Uint8ClampedArrayOrUint16ArrayOrFloat32Array.cpp",
+  "$bindings_core_v8_output_dir/Uint8ClampedArrayOrUint16ArrayOrFloat32Array.h",
   "$bindings_core_v8_output_dir/VideoTrackOrAudioTrackOrTextTrack.cpp",
   "$bindings_core_v8_output_dir/VideoTrackOrAudioTrackOrTextTrack.h",
 ]
diff --git a/third_party/WebKit/Source/bindings/core/v8/DOMWrapperWorld.cpp b/third_party/WebKit/Source/bindings/core/v8/DOMWrapperWorld.cpp
index 4593c3ef..24b1935d 100644
--- a/third_party/WebKit/Source/bindings/core/v8/DOMWrapperWorld.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/DOMWrapperWorld.cpp
@@ -83,11 +83,25 @@
 
 unsigned DOMWrapperWorld::s_numberOfNonMainWorldsInMainThread = 0;
 
+using WorldMap = HashMap<int, DOMWrapperWorld*>;
+
+static WorldMap& isolatedWorldMap() {
+  DCHECK(isMainThread());
+  DEFINE_STATIC_LOCAL(WorldMap, map, ());
+  return map;
+}
+
+static WorldMap& worldMap() {
+  DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<WorldMap>, map,
+                                  new ThreadSpecific<WorldMap>);
+  return *map;
+}
+
 PassRefPtr<DOMWrapperWorld> DOMWrapperWorld::create(v8::Isolate* isolate,
                                                     WorldType worldType) {
   DCHECK_NE(WorldType::Isolated, worldType);
-  return adoptRef(
-      new DOMWrapperWorld(isolate, worldType, getWorldIdForType(worldType)));
+  return adoptRef(new DOMWrapperWorld(isolate, worldType,
+                                      generateWorldIdForType(worldType)));
 }
 
 DOMWrapperWorld::DOMWrapperWorld(v8::Isolate* isolate,
@@ -97,8 +111,28 @@
       m_worldId(worldId),
       m_domDataStore(
           WTF::wrapUnique(new DOMDataStore(isolate, isMainWorld()))) {
-  if (isWorkerWorld())
-    workerWorld() = this;
+  switch (worldType) {
+    case WorldType::Main:
+      // MainWorld is managed separately from worldMap() and isolatedWorldMap().
+      // See mainWorld().
+      break;
+    case WorldType::Isolated: {
+      DCHECK(isMainThread());
+      WorldMap& map = isolatedWorldMap();
+      DCHECK(!map.contains(worldId));
+      map.insert(worldId, this);
+      break;
+    }
+    case WorldType::GarbageCollector:
+    case WorldType::RegExp:
+    case WorldType::Testing:
+    case WorldType::Worker: {
+      WorldMap& map = worldMap();
+      DCHECK(!map.contains(worldId));
+      map.insert(worldId, this);
+      break;
+    }
+  }
   if (worldId != WorldId::MainWorldId && isMainThread())
     s_numberOfNonMainWorldsInMainThread++;
 }
@@ -111,12 +145,6 @@
   return *cachedMainWorld;
 }
 
-DOMWrapperWorld*& DOMWrapperWorld::workerWorld() {
-  DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<DOMWrapperWorld*>, workerWorld,
-                                  new ThreadSpecific<DOMWrapperWorld*>);
-  return *workerWorld;
-}
-
 PassRefPtr<DOMWrapperWorld> DOMWrapperWorld::fromWorldId(v8::Isolate* isolate,
                                                          int worldId) {
   if (worldId == MainWorldId)
@@ -124,47 +152,40 @@
   return ensureIsolatedWorld(isolate, worldId);
 }
 
-typedef HashMap<int, DOMWrapperWorld*> WorldMap;
-static WorldMap& isolatedWorldMap() {
-  ASSERT(isMainThread());
-  DEFINE_STATIC_LOCAL(WorldMap, map, ());
-  return map;
-}
-
 void DOMWrapperWorld::allWorldsInMainThread(
     Vector<RefPtr<DOMWrapperWorld>>& worlds) {
   ASSERT(isMainThread());
   worlds.push_back(&mainWorld());
-  WorldMap& isolatedWorlds = isolatedWorldMap();
-  for (WorldMap::iterator it = isolatedWorlds.begin();
-       it != isolatedWorlds.end(); ++it)
-    worlds.push_back(it->value);
+  for (DOMWrapperWorld* world : worldMap().values())
+    worlds.push_back(world);
+  for (DOMWrapperWorld* world : isolatedWorldMap().values())
+    worlds.push_back(world);
 }
 
 void DOMWrapperWorld::markWrappersInAllWorlds(
     ScriptWrappable* scriptWrappable,
     const ScriptWrappableVisitor* visitor) {
-  // Handle marking in per-worker wrapper worlds.
-  if (!isMainThread()) {
-    DCHECK(ThreadState::current()->isolate());
-    DOMWrapperWorld* worker = workerWorld();
-    if (worker) {
-      DOMDataStore& dataStore = worker->domDataStore();
-      if (dataStore.containsWrapper(scriptWrappable)) {
-        dataStore.markWrapper(scriptWrappable);
-      }
-    }
-    return;
+  // Marking for worlds other than the main world and the isolated worlds.
+  DCHECK(ThreadState::current()->isolate());
+  for (DOMWrapperWorld* world : worldMap().values()) {
+    DOMDataStore& dataStore = world->domDataStore();
+    if (dataStore.containsWrapper(scriptWrappable))
+      dataStore.markWrapper(scriptWrappable);
   }
 
+  // The main world and isolated worlds should exist only on the main thread.
+  if (!isMainThread())
+    return;
+
+  // Marking for the main world.
   scriptWrappable->markWrapper(visitor);
+
+  // Marking for the isolated worlds.
   WorldMap& isolatedWorlds = isolatedWorldMap();
   for (auto& world : isolatedWorlds.values()) {
     DOMDataStore& dataStore = world->domDataStore();
-    if (dataStore.containsWrapper(scriptWrappable)) {
-      // Marking for the isolated worlds
+    if (dataStore.containsWrapper(scriptWrappable))
       dataStore.markWrapper(scriptWrappable);
-    }
   }
 }
 
@@ -193,8 +214,7 @@
 void DOMWrapperWorld::dispose() {
   m_domObjectHolders.clear();
   m_domDataStore.reset();
-  if (isWorkerWorld())
-    workerWorld() = nullptr;
+  worldMap().remove(m_worldId);
 }
 
 #if DCHECK_IS_ON()
@@ -210,16 +230,14 @@
   ASSERT(isIsolatedWorldId(worldId));
 
   WorldMap& map = isolatedWorldMap();
-  WorldMap::AddResult result = map.insert(worldId, nullptr);
-  RefPtr<DOMWrapperWorld> world = result.storedValue->value;
-  if (world) {
-    ASSERT(world->worldId() == worldId);
+  auto it = map.find(worldId);
+  if (it != map.end()) {
+    RefPtr<DOMWrapperWorld> world = it->value;
+    DCHECK_EQ(worldId, world->worldId());
     return world.release();
   }
 
-  world = adoptRef(new DOMWrapperWorld(isolate, WorldType::Isolated, worldId));
-  result.storedValue->value = world.get();
-  return world.release();
+  return adoptRef(new DOMWrapperWorld(isolate, WorldType::Isolated, worldId));
 }
 
 typedef HashMap<int, RefPtr<SecurityOrigin>> IsolatedWorldSecurityOriginMap;
@@ -323,7 +341,11 @@
   holderBase->world()->unregisterDOMObjectHolder(holderBase);
 }
 
-int DOMWrapperWorld::getWorldIdForType(WorldType worldType) {
+int DOMWrapperWorld::generateWorldIdForType(WorldType worldType) {
+  DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<int>, s_nextWorldId,
+                                  new ThreadSpecific<int>);
+  if (!s_nextWorldId.isSet())
+    *s_nextWorldId = WorldId::UnspecifiedWorldIdStart;
   switch (worldType) {
     case WorldType::Main:
       return MainWorldId;
@@ -333,17 +355,13 @@
       NOTREACHED();
       return InvalidWorldId;
     case WorldType::GarbageCollector:
-      return GarbageCollectorWorldId;
     case WorldType::RegExp:
-      return RegExpWorldId;
     case WorldType::Testing:
-      return TestingWorldId;
-    // Currently, WorldId for a worker/worklet is a fixed value, but this
-    // doesn't work when multiple worklets are created on a thread.
-    // TODO(nhiroki): Expand the identifier space for workers/worklets.
-    // (https://crbug.com/697622)
     case WorldType::Worker:
-      return WorkerWorldId;
+      int worldId = *s_nextWorldId;
+      CHECK_GE(worldId, WorldId::UnspecifiedWorldIdStart);
+      *s_nextWorldId = worldId + 1;
+      return worldId;
   }
   NOTREACHED();
   return InvalidWorldId;
diff --git a/third_party/WebKit/Source/bindings/core/v8/DOMWrapperWorld.h b/third_party/WebKit/Source/bindings/core/v8/DOMWrapperWorld.h
index fefb76d..d4821bd4 100644
--- a/third_party/WebKit/Source/bindings/core/v8/DOMWrapperWorld.h
+++ b/third_party/WebKit/Source/bindings/core/v8/DOMWrapperWorld.h
@@ -61,12 +61,9 @@
     DocumentXMLTreeViewerWorldId,
     IsolatedWorldIdLimit,
 
-    // TODO(nhiroki): Dynamically allocate a world id for the following worlds
-    // instead of a fixed value (https://crbug.com/697622).
-    GarbageCollectorWorldId,
-    RegExpWorldId,
-    TestingWorldId,
-    WorkerWorldId,
+    // Other worlds can use IDs after this. Don't manually pick up an ID from
+    // this range. generateWorldIdForType() picks it up on behalf of you.
+    UnspecifiedWorldIdStart,
   };
 
   enum class WorldType {
@@ -149,10 +146,10 @@
 
   static unsigned s_numberOfNonMainWorldsInMainThread;
 
-  // Returns an identifier for a given world type. This must not call for
+  // Returns an identifier for a given world type. This must not be called for
   // WorldType::IsolatedWorld because an identifier for the world is given from
   // out of DOMWrapperWorld.
-  static int getWorldIdForType(WorldType);
+  static int generateWorldIdForType(WorldType);
 
   const WorldType m_worldType;
   const int m_worldId;
diff --git a/third_party/WebKit/Source/core/core_idl_files.gni b/third_party/WebKit/Source/core/core_idl_files.gni
index 569c9c17..1a0633a 100644
--- a/third_party/WebKit/Source/core/core_idl_files.gni
+++ b/third_party/WebKit/Source/core/core_idl_files.gni
@@ -197,7 +197,6 @@
                                  "frame/ImageBitmap.idl",
                                  "frame/Location.idl",
                                  "frame/VisualViewport.idl",
-                                 "html/Float32ImageData.idl",
                                  "html/FormData.idl",
                                  "html/HTMLAllCollection.idl",
                                  "html/HTMLAnchorElement.idl",
@@ -563,6 +562,7 @@
                     "frame/ScrollOptions.idl",
                     "frame/ScrollToOptions.idl",
                     "html/AssignedNodesOptions.idl",
+                    "html/ImageDataColorSettings.idl",
                     "html/canvas/CanvasContextCreationAttributes.idl",
                     "html/track/TrackEventInit.idl",
                     "imagebitmap/ImageBitmapOptions.idl",
diff --git a/third_party/WebKit/Source/core/css/CSSSelector.cpp b/third_party/WebKit/Source/core/css/CSSSelector.cpp
index c8f8366..f45b9bf1 100644
--- a/third_party/WebKit/Source/core/css/CSSSelector.cpp
+++ b/third_party/WebKit/Source/core/css/CSSSelector.cpp
@@ -289,16 +289,6 @@
     {"-internal-list-box", CSSSelector::PseudoListBox},
     {"-internal-media-controls-overlay-cast-button",
      CSSSelector::PseudoWebKitCustomElement},
-    {"-internal-media-controls-text-track-list",
-     CSSSelector::PseudoWebKitCustomElement},
-    {"-internal-media-controls-text-track-list-item",
-     CSSSelector::PseudoWebKitCustomElement},
-    {"-internal-media-controls-text-track-list-item-input",
-     CSSSelector::PseudoWebKitCustomElement},
-    {"-internal-media-controls-text-track-list-kind-captions",
-     CSSSelector::PseudoWebKitCustomElement},
-    {"-internal-media-controls-text-track-list-kind-subtitles",
-     CSSSelector::PseudoWebKitCustomElement},
     {"-internal-shadow-host-has-appearance",
      CSSSelector::PseudoHostHasAppearance},
     {"-internal-spatial-navigation-focus",
diff --git a/third_party/WebKit/Source/core/css/parser/CSSSelectorParser.cpp b/third_party/WebKit/Source/core/css/parser/CSSSelectorParser.cpp
index a676948..d88f00a6 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSSelectorParser.cpp
+++ b/third_party/WebKit/Source/core/css/parser/CSSSelectorParser.cpp
@@ -854,28 +854,6 @@
                 "-internal-media-controls-overlay-cast-button") {
               feature =
                   UseCounter::CSSSelectorInternalMediaControlsOverlayCastButton;
-            } else if (current->value() ==
-                       "-internal-media-controls-text-track-list") {
-              feature =
-                  UseCounter::CSSSelectorInternalMediaControlsTextTrackList;
-            } else if (current->value() ==
-                       "-internal-media-controls-text-track-list-item") {
-              feature =
-                  UseCounter::CSSSelectorInternalMediaControlsTextTrackListItem;
-            } else if (current->value() ==
-                       "-internal-media-controls-text-track-list-item-input") {
-              feature = UseCounter::
-                  CSSSelectorInternalMediaControlsTextTrackListItemInput;
-            } else if (current->value() ==
-                       "-internal-media-controls-text-track-list-kind-"
-                       "captions") {
-              feature = UseCounter::
-                  CSSSelectorInternalMediaControlsTextTrackListKindCaptions;
-            } else if (current->value() ==
-                       "-internal-media-controls-text-track-list-kind-"
-                       "subtitles") {
-              feature = UseCounter::
-                  CSSSelectorInternalMediaControlsTextTrackListKindSubtitles;
             }
           }
           break;
diff --git a/third_party/WebKit/Source/core/dom/StaticRange.h b/third_party/WebKit/Source/core/dom/StaticRange.h
index 551efd9..fa007e37 100644
--- a/third_party/WebKit/Source/core/dom/StaticRange.h
+++ b/third_party/WebKit/Source/core/dom/StaticRange.h
@@ -10,6 +10,7 @@
 #include "bindings/core/v8/ScriptWrappable.h"
 #include "core/CoreExport.h"
 #include "core/dom/Range.h"
+#include "core/editing/EphemeralRange.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
@@ -38,6 +39,14 @@
                            range->startOffset(), range->endContainer(),
                            range->endOffset());
   }
+  static StaticRange* create(const EphemeralRange& range) {
+    DCHECK(!range.isNull());
+    return new StaticRange(range.document(),
+                           range.startPosition().computeContainerNode(),
+                           range.startPosition().computeOffsetInContainerNode(),
+                           range.endPosition().computeContainerNode(),
+                           range.endPosition().computeOffsetInContainerNode());
+  }
 
   Node* startContainer() const { return m_startContainer.get(); }
   void setStartContainer(Node* startContainer) {
diff --git a/third_party/WebKit/Source/core/editing/EditingUtilities.cpp b/third_party/WebKit/Source/core/editing/EditingUtilities.cpp
index 93f3cf5..76af4bce 100644
--- a/third_party/WebKit/Source/core/editing/EditingUtilities.cpp
+++ b/third_party/WebKit/Source/core/editing/EditingUtilities.cpp
@@ -2081,14 +2081,17 @@
 }
 
 const StaticRangeVector* targetRangesForInputEvent(const Node& node) {
+  // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets
+  // needs to be audited. see http://crbug.com/590369 for more details.
+  node.document().updateStyleAndLayoutIgnorePendingStylesheets();
   if (!hasRichlyEditableStyle(node))
     return nullptr;
-  Range* range = createRange(
+  const EphemeralRange& range =
       firstEphemeralRangeOf(node.document()
                                 .frame()
                                 ->selection()
-                                .computeVisibleSelectionInDOMTreeDeprecated()));
-  if (!range)
+                                .computeVisibleSelectionInDOMTreeDeprecated());
+  if (range.isNull())
     return nullptr;
   return new StaticRangeVector(1, StaticRange::create(range));
 }
diff --git a/third_party/WebKit/Source/core/editing/commands/EditorCommand.cpp b/third_party/WebKit/Source/core/editing/commands/EditorCommand.cpp
index 89c11ce7..b5efe06 100644
--- a/third_party/WebKit/Source/core/editing/commands/EditorCommand.cpp
+++ b/third_party/WebKit/Source/core/editing/commands/EditorCommand.cpp
@@ -207,7 +207,7 @@
   if (selectionModifier.selection().isNone())
     return ranges;
   ranges->push_back(StaticRange::create(
-      createRange(firstEphemeralRangeOf(selectionModifier.selection()))));
+      firstEphemeralRangeOf(selectionModifier.selection())));
   return ranges;
 }
 
diff --git a/third_party/WebKit/Source/core/frame/Deprecation.cpp b/third_party/WebKit/Source/core/frame/Deprecation.cpp
index dfaefb2..6fa62494 100644
--- a/third_party/WebKit/Source/core/frame/Deprecation.cpp
+++ b/third_party/WebKit/Source/core/frame/Deprecation.cpp
@@ -394,15 +394,6 @@
           "-internal-media-controls-overlay-cast-button selector", M59,
           "5714245488476160");
 
-    case UseCounter::CSSSelectorInternalMediaControlsTextTrackList:
-    case UseCounter::CSSSelectorInternalMediaControlsTextTrackListItem:
-    case UseCounter::CSSSelectorInternalMediaControlsTextTrackListItemInput:
-    case UseCounter::CSSSelectorInternalMediaControlsTextTrackListKindCaptions:
-    case UseCounter::CSSSelectorInternalMediaControlsTextTrackListKindSubtitles:
-      return willBeRemoved(
-          "-internal-media-controls-text-track-list* selectors", M59,
-          "5661431349379072");
-
     case UseCounter::FileReaderSyncInServiceWorker:
       return willBeRemoved("FileReaderSync in service workers", M59,
                            "5739144722513920");
diff --git a/third_party/WebKit/Source/core/frame/ImageBitmap.cpp b/third_party/WebKit/Source/core/frame/ImageBitmap.cpp
index bb8b6be6..a737bfb 100644
--- a/third_party/WebKit/Source/core/frame/ImageBitmap.cpp
+++ b/third_party/WebKit/Source/core/frame/ImageBitmap.cpp
@@ -4,7 +4,6 @@
 
 #include "core/frame/ImageBitmap.h"
 
-#include "core/html/Float32ImageData.h"
 #include "core/html/HTMLCanvasElement.h"
 #include "core/html/HTMLVideoElement.h"
 #include "core/html/ImageData.h"
@@ -932,11 +931,6 @@
   m_image = StaticBitmapImage::create(std::move(skImage));
 }
 
-// TODO(zakerinasab): Fix the constructor from Float32ImageData.
-ImageBitmap::ImageBitmap(Float32ImageData* data,
-                         Optional<IntRect> cropRect,
-                         const ImageBitmapOptions& options) {}
-
 ImageBitmap::ImageBitmap(ImageBitmap* bitmap,
                          Optional<IntRect> cropRect,
                          const ImageBitmapOptions& options) {
@@ -1021,12 +1015,6 @@
   return new ImageBitmap(data, cropRect, options);
 }
 
-ImageBitmap* ImageBitmap::create(Float32ImageData* data,
-                                 Optional<IntRect> cropRect,
-                                 const ImageBitmapOptions& options) {
-  return new ImageBitmap(data, cropRect, options);
-}
-
 ImageBitmap* ImageBitmap::create(ImageBitmap* bitmap,
                                  Optional<IntRect> cropRect,
                                  const ImageBitmapOptions& options) {
diff --git a/third_party/WebKit/Source/core/frame/ImageBitmap.h b/third_party/WebKit/Source/core/frame/ImageBitmap.h
index eab4930..99fd4d5 100644
--- a/third_party/WebKit/Source/core/frame/ImageBitmap.h
+++ b/third_party/WebKit/Source/core/frame/ImageBitmap.h
@@ -21,7 +21,6 @@
 #include <memory>
 
 namespace blink {
-class Float32ImageData;
 class HTMLCanvasElement;
 class HTMLVideoElement;
 class ImageData;
@@ -66,9 +65,6 @@
   static ImageBitmap* create(ImageData*,
                              Optional<IntRect>,
                              const ImageBitmapOptions& = ImageBitmapOptions());
-  static ImageBitmap* create(Float32ImageData*,
-                             Optional<IntRect>,
-                             const ImageBitmapOptions& = ImageBitmapOptions());
   static ImageBitmap* create(ImageBitmap*,
                              Optional<IntRect>,
                              const ImageBitmapOptions& = ImageBitmapOptions());
@@ -154,7 +150,6 @@
   ImageBitmap(HTMLCanvasElement*, Optional<IntRect>, const ImageBitmapOptions&);
   ImageBitmap(OffscreenCanvas*, Optional<IntRect>, const ImageBitmapOptions&);
   ImageBitmap(ImageData*, Optional<IntRect>, const ImageBitmapOptions&);
-  ImageBitmap(Float32ImageData*, Optional<IntRect>, const ImageBitmapOptions&);
   ImageBitmap(ImageBitmap*, Optional<IntRect>, const ImageBitmapOptions&);
   ImageBitmap(PassRefPtr<StaticBitmapImage>);
   ImageBitmap(PassRefPtr<StaticBitmapImage>,
diff --git a/third_party/WebKit/Source/core/frame/ImageBitmapTest.cpp b/third_party/WebKit/Source/core/frame/ImageBitmapTest.cpp
index 10ba563..63db6b16 100644
--- a/third_party/WebKit/Source/core/frame/ImageBitmapTest.cpp
+++ b/third_party/WebKit/Source/core/frame/ImageBitmapTest.cpp
@@ -490,8 +490,7 @@
 TEST_F(ImageBitmapTest, ImageBitmapColorSpaceConversionImageData) {
   unsigned char dataBuffer[4] = {255, 0, 0, 255};
   DOMUint8ClampedArray* data = DOMUint8ClampedArray::create(dataBuffer, 4);
-  ImageData* imageData =
-      ImageData::create(IntSize(1, 1), data, kLegacyImageDataColorSpaceName);
+  ImageData* imageData = ImageData::create(IntSize(1, 1), data);
   std::unique_ptr<uint8_t[]> srcPixel(new uint8_t[4]());
   memcpy(srcPixel.get(), imageData->data()->data(), 4);
 
diff --git a/third_party/WebKit/Source/core/frame/UseCounter.h b/third_party/WebKit/Source/core/frame/UseCounter.h
index 9c6ef824..4262987 100644
--- a/third_party/WebKit/Source/core/frame/UseCounter.h
+++ b/third_party/WebKit/Source/core/frame/UseCounter.h
@@ -1395,11 +1395,6 @@
     DocumentCompleteURLHTTPContainingNewline = 1768,
     DocumentCompleteURLHTTPContainingNewlineAndLessThan = 1770,
     DocumentCompleteURLNonHTTPContainingNewline = 1771,
-    CSSSelectorInternalMediaControlsTextTrackList = 1772,
-    CSSSelectorInternalMediaControlsTextTrackListItem = 1773,
-    CSSSelectorInternalMediaControlsTextTrackListItemInput = 1774,
-    CSSSelectorInternalMediaControlsTextTrackListKindCaptions = 1775,
-    CSSSelectorInternalMediaControlsTextTrackListKindSubtitles = 1776,
     ScrollbarUseVerticalScrollbarButton = 1777,
     ScrollbarUseVerticalScrollbarThumb = 1778,
     ScrollbarUseVerticalScrollbarTrack = 1779,
diff --git a/third_party/WebKit/Source/core/html/BUILD.gn b/third_party/WebKit/Source/core/html/BUILD.gn
index 28b883f..bcf57722 100644
--- a/third_party/WebKit/Source/core/html/BUILD.gn
+++ b/third_party/WebKit/Source/core/html/BUILD.gn
@@ -17,8 +17,6 @@
     "CrossOriginAttribute.h",
     "DocumentNameCollection.cpp",
     "DocumentNameCollection.h",
-    "Float32ImageData.cpp",
-    "Float32ImageData.h",
     "FormAssociated.h",
     "FormData.cpp",
     "FormData.h",
diff --git a/third_party/WebKit/Source/core/html/Float32ImageData.cpp b/third_party/WebKit/Source/core/html/Float32ImageData.cpp
deleted file mode 100644
index 544e19e4..0000000
--- a/third_party/WebKit/Source/core/html/Float32ImageData.cpp
+++ /dev/null
@@ -1,173 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "core/html/Float32ImageData.h"
-
-#include "bindings/core/v8/ExceptionState.h"
-#include "bindings/core/v8/V8Float32Array.h"
-#include "core/dom/ExceptionCode.h"
-#include "core/frame/ImageBitmap.h"
-#include "core/imagebitmap/ImageBitmapOptions.h"
-#include "platform/RuntimeEnabledFeatures.h"
-#include "wtf/CheckedNumeric.h"
-
-namespace blink {
-
-bool Float32ImageData::validateConstructorArguments(
-    const unsigned& paramFlags,
-    const IntSize* size,
-    const unsigned& width,
-    const unsigned& height,
-    const DOMFloat32Array* data,
-    const String* colorSpace,
-    ExceptionState* exceptionState) {
-  return ImageData::validateConstructorArguments(
-      paramFlags, size, width, height, data, colorSpace, exceptionState,
-      kFloat32ImageData);
-}
-
-DOMFloat32Array* Float32ImageData::allocateAndValidateFloat32Array(
-    const unsigned& length,
-    ExceptionState* exceptionState) {
-  if (!length)
-    return nullptr;
-  DOMFloat32Array* dataArray = DOMFloat32Array::createOrNull(length);
-  if (!dataArray || length != dataArray->length()) {
-    if (exceptionState) {
-      exceptionState->throwDOMException(
-          V8RangeError, "Out of memory at Float32ImageData creation");
-    }
-    return nullptr;
-  }
-  return dataArray;
-}
-
-Float32ImageData* Float32ImageData::create(const IntSize& size) {
-  if (!Float32ImageData::validateConstructorArguments(kParamSize, &size))
-    return nullptr;
-  DOMFloat32Array* dataArray =
-      Float32ImageData::allocateAndValidateFloat32Array(4 * size.width() *
-                                                        size.height());
-  return dataArray ? new Float32ImageData(size, dataArray) : nullptr;
-}
-
-Float32ImageData* Float32ImageData::create(const IntSize& size,
-                                           DOMFloat32Array* dataArray) {
-  if (!Float32ImageData::validateConstructorArguments(kParamSize | kParamData,
-                                                      &size, 0, 0, dataArray))
-    return nullptr;
-  return new Float32ImageData(size, dataArray);
-}
-
-Float32ImageData* Float32ImageData::create(unsigned width,
-                                           unsigned height,
-                                           ExceptionState& exceptionState) {
-  if (!Float32ImageData::validateConstructorArguments(
-          kParamWidth | kParamHeight, nullptr, width, height, nullptr, nullptr,
-          &exceptionState))
-    return nullptr;
-  DOMFloat32Array* dataArray =
-      Float32ImageData::allocateAndValidateFloat32Array(4 * width * height,
-                                                        &exceptionState);
-  return dataArray ? new Float32ImageData(IntSize(width, height), dataArray)
-                   : nullptr;
-}
-
-Float32ImageData* Float32ImageData::create(DOMFloat32Array* data,
-                                           unsigned width,
-                                           ExceptionState& exceptionState) {
-  if (!Float32ImageData::validateConstructorArguments(kParamData | kParamWidth,
-                                                      nullptr, width, 0, data,
-                                                      nullptr, &exceptionState))
-    return nullptr;
-  unsigned height = data->length() / (width * 4);
-  return new Float32ImageData(IntSize(width, height), data);
-}
-
-Float32ImageData* Float32ImageData::create(DOMFloat32Array* data,
-                                           unsigned width,
-                                           unsigned height,
-                                           ExceptionState& exceptionState) {
-  if (!Float32ImageData::validateConstructorArguments(
-          kParamData | kParamWidth | kParamHeight, nullptr, width, height, data,
-          nullptr, &exceptionState))
-    return nullptr;
-  return new Float32ImageData(IntSize(width, height), data);
-}
-
-Float32ImageData* Float32ImageData::create(unsigned width,
-                                           unsigned height,
-                                           String colorSpace,
-                                           ExceptionState& exceptionState) {
-  if (!Float32ImageData::validateConstructorArguments(
-          kParamWidth | kParamHeight | kParamColorSpace, nullptr, width, height,
-          nullptr, &colorSpace, &exceptionState))
-    return nullptr;
-
-  DOMFloat32Array* dataArray =
-      Float32ImageData::allocateAndValidateFloat32Array(4 * width * height,
-                                                        &exceptionState);
-  return dataArray ? new Float32ImageData(IntSize(width, height), dataArray,
-                                          colorSpace)
-                   : nullptr;
-}
-
-Float32ImageData* Float32ImageData::create(DOMFloat32Array* data,
-                                           unsigned width,
-                                           String colorSpace,
-                                           ExceptionState& exceptionState) {
-  if (!Float32ImageData::validateConstructorArguments(
-          kParamData | kParamWidth | kParamColorSpace, nullptr, width, 0, data,
-          &colorSpace, &exceptionState))
-    return nullptr;
-  unsigned height = data->length() / (width * 4);
-  return new Float32ImageData(IntSize(width, height), data, colorSpace);
-}
-
-Float32ImageData* Float32ImageData::create(DOMFloat32Array* data,
-                                           unsigned width,
-                                           unsigned height,
-                                           String colorSpace,
-                                           ExceptionState& exceptionState) {
-  if (!Float32ImageData::validateConstructorArguments(
-          kParamData | kParamWidth | kParamHeight | kParamColorSpace, nullptr,
-          width, height, data, &colorSpace, &exceptionState))
-    return nullptr;
-  return new Float32ImageData(IntSize(width, height), data, colorSpace);
-}
-
-v8::Local<v8::Object> Float32ImageData::associateWithWrapper(
-    v8::Isolate* isolate,
-    const WrapperTypeInfo* wrapperType,
-    v8::Local<v8::Object> wrapper) {
-  wrapper =
-      ScriptWrappable::associateWithWrapper(isolate, wrapperType, wrapper);
-
-  if (!wrapper.IsEmpty() && m_data.get()) {
-    // Create a V8 Float32Array object and set the "data" property
-    // of the Float32ImageData object to the created v8 object, eliminating the
-    // C++ callback when accessing the "data" property.
-    v8::Local<v8::Value> pixelArray = ToV8(m_data.get(), wrapper, isolate);
-    if (pixelArray.IsEmpty() ||
-        !v8CallBoolean(wrapper->DefineOwnProperty(
-            isolate->GetCurrentContext(), v8AtomicString(isolate, "data"),
-            pixelArray, v8::ReadOnly)))
-      return v8::Local<v8::Object>();
-  }
-  return wrapper;
-}
-
-Float32ImageData::Float32ImageData(const IntSize& size,
-                                   DOMFloat32Array* dataArray,
-                                   String colorSpaceName)
-    : m_size(size),
-      m_colorSpace(ImageData::getImageDataColorSpace(colorSpaceName)),
-      m_data(dataArray) {
-  DCHECK_GE(size.width(), 0);
-  DCHECK_GE(size.height(), 0);
-  SECURITY_CHECK(static_cast<unsigned>(size.width() * size.height() * 4) <=
-                 m_data->length());
-}
-
-}  // namespace blink
diff --git a/third_party/WebKit/Source/core/html/Float32ImageData.h b/third_party/WebKit/Source/core/html/Float32ImageData.h
deleted file mode 100644
index 5247feb..0000000
--- a/third_party/WebKit/Source/core/html/Float32ImageData.h
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef Float32ImageData_h
-#define Float32ImageData_h
-
-#include "bindings/core/v8/ScriptWrappable.h"
-#include "core/CoreExport.h"
-#include "core/dom/DOMTypedArray.h"
-#include "core/html/ImageData.h"
-#include "core/imagebitmap/ImageBitmapSource.h"
-#include "platform/geometry/IntRect.h"
-#include "platform/geometry/IntSize.h"
-#include "platform/heap/Handle.h"
-#include "wtf/Compiler.h"
-#include "wtf/text/WTFString.h"
-
-namespace blink {
-
-class ExceptionState;
-
-class CORE_EXPORT Float32ImageData final
-    : public GarbageCollected<Float32ImageData>,
-      public ScriptWrappable {
-  DEFINE_WRAPPERTYPEINFO();
-
- public:
-  static Float32ImageData* create(const IntSize&);
-  static Float32ImageData* create(const IntSize&, DOMFloat32Array*);
-  static Float32ImageData* create(unsigned width,
-                                  unsigned height,
-                                  ExceptionState&);
-  static Float32ImageData* create(unsigned width,
-                                  unsigned height,
-                                  String colorSpace,
-                                  ExceptionState&);
-  static Float32ImageData* create(DOMFloat32Array*,
-                                  unsigned width,
-                                  ExceptionState&);
-  static Float32ImageData* create(DOMFloat32Array*,
-                                  unsigned width,
-                                  String colorSpace,
-                                  ExceptionState&);
-  static Float32ImageData* create(DOMFloat32Array*,
-                                  unsigned width,
-                                  unsigned height,
-                                  ExceptionState&);
-  static Float32ImageData* create(DOMFloat32Array*,
-                                  unsigned width,
-                                  unsigned height,
-                                  String colorSpace,
-                                  ExceptionState&);
-
-  IntSize size() const { return m_size; }
-  int width() const { return m_size.width(); }
-  int height() const { return m_size.height(); }
-  String colorSpace() const {
-    return ImageData::getImageDataColorSpaceName(m_colorSpace);
-  }
-  ImageDataColorSpace imageDataColorSpace() { return m_colorSpace; }
-  const DOMFloat32Array* data() const { return m_data; }
-  DOMFloat32Array* data() { return m_data; }
-
-  DEFINE_INLINE_TRACE() { visitor->trace(m_data); }
-
-  WARN_UNUSED_RESULT v8::Local<v8::Object> associateWithWrapper(
-      v8::Isolate*,
-      const WrapperTypeInfo*,
-      v8::Local<v8::Object> wrapper) override;
-
- private:
-  Float32ImageData(const IntSize&,
-                   DOMFloat32Array*,
-                   String = kLinearRGBImageDataColorSpaceName);
-
-  IntSize m_size;
-  ImageDataColorSpace m_colorSpace;
-  Member<DOMFloat32Array> m_data;
-
-  static bool validateConstructorArguments(const unsigned&,
-                                           const IntSize* = nullptr,
-                                           const unsigned& = 0,
-                                           const unsigned& = 0,
-                                           const DOMFloat32Array* = nullptr,
-                                           const String* = nullptr,
-                                           ExceptionState* = nullptr);
-
-  static DOMFloat32Array* allocateAndValidateFloat32Array(
-      const unsigned&,
-      ExceptionState* = nullptr);
-};
-
-}  // namespace blink
-
-#endif  // Float32ImageData_h
diff --git a/third_party/WebKit/Source/core/html/Float32ImageData.idl b/third_party/WebKit/Source/core/html/Float32ImageData.idl
deleted file mode 100644
index 9446a3c..0000000
--- a/third_party/WebKit/Source/core/html/Float32ImageData.idl
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// https://github.com/junov/CanvasColorSpace/blob/master/CanvasColorSpaceProposal.md#imagedata
-
-[
-    Constructor(unsigned long sw, unsigned long sh),
-    Constructor(unsigned long sw, unsigned long sh, ImageDataColorSpace colorSpace),
-    Constructor(Float32Array data, unsigned long sw),
-    Constructor(Float32Array data, unsigned long sw, unsigned long sh),
-    Constructor(Float32Array data, unsigned long sw, unsigned long sh, ImageDataColorSpace colorSpace),
-
-    Exposed=(Window,Worker),
-    RaisesException=Constructor,
-    RuntimeEnabled=ExperimentalCanvasFeatures,
-] interface Float32ImageData {
-    readonly attribute unsigned long width;
-    readonly attribute unsigned long height;
-    readonly attribute Float32Array data;
-    readonly attribute ImageDataColorSpace colorSpace;
-};
diff --git a/third_party/WebKit/Source/core/html/ImageData.cpp b/third_party/WebKit/Source/core/html/ImageData.cpp
index ae78044..ffa7a11 100644
--- a/third_party/WebKit/Source/core/html/ImageData.cpp
+++ b/third_party/WebKit/Source/core/html/ImageData.cpp
@@ -38,24 +38,89 @@
 
 namespace blink {
 
+bool RaiseDOMExceptionAndReturnFalse(ExceptionState* exceptionState,
+                                     ExceptionCode exceptionCode,
+                                     const char* message) {
+  if (exceptionState)
+    exceptionState->throwDOMException(exceptionCode, message);
+  return false;
+}
+
 bool ImageData::validateConstructorArguments(const unsigned& paramFlags,
                                              const IntSize* size,
                                              const unsigned& width,
                                              const unsigned& height,
                                              const DOMArrayBufferView* data,
-                                             const String* colorSpace,
-                                             ExceptionState* exceptionState,
-                                             ImageDataType imageDataType) {
-  if (paramFlags & kParamData) {
-    if (data->type() != DOMArrayBufferView::ViewType::TypeUint8Clamped &&
-        data->type() != DOMArrayBufferView::ViewType::TypeFloat32)
-      return false;
-    if (data->type() == DOMArrayBufferView::ViewType::TypeUint8Clamped &&
-        imageDataType != kUint8ClampedImageData)
-      imageDataType = kFloat32ImageData;
+                                             ExceptionState* exceptionState) {
+  // We accept all the combinations of colorSpace and storageFormat in an
+  // ImageDataColorSettings to be stored in an ImageData. Therefore, we don't
+  // check the color settings in this function.
+
+  if ((paramFlags & kParamWidth) && !width) {
+    return RaiseDOMExceptionAndReturnFalse(
+        exceptionState, IndexSizeError,
+        "The source width is zero or not a number.");
   }
 
-  // ImageData::create parameters without ExceptionState
+  if ((paramFlags & kParamHeight) && !height) {
+    return RaiseDOMExceptionAndReturnFalse(
+        exceptionState, IndexSizeError,
+        "The source height is zero or not a number.");
+  }
+
+  if (paramFlags & (kParamWidth | kParamHeight)) {
+    CheckedNumeric<unsigned> dataSize = 4;
+    dataSize *= width;
+    dataSize *= height;
+    if (!dataSize.IsValid())
+      return RaiseDOMExceptionAndReturnFalse(
+          exceptionState, IndexSizeError,
+          "The requested image size exceeds the supported range.");
+  }
+
+  unsigned dataLength = 0;
+  if (paramFlags & kParamData) {
+    DCHECK(data);
+    switch (data->type()) {
+      case DOMArrayBufferView::ViewType::TypeUint8Clamped:
+        dataLength = data->view()->byteLength();
+        break;
+      case DOMArrayBufferView::ViewType::TypeUint16:
+        dataLength = data->view()->byteLength() / 2;
+        break;
+      case DOMArrayBufferView::ViewType::TypeFloat32:
+        dataLength = data->view()->byteLength() / 4;
+        break;
+      default:
+        return RaiseDOMExceptionAndReturnFalse(
+            exceptionState, NotSupportedError,
+            "The input data type is not supported.");
+    }
+
+    if (!dataLength) {
+      return RaiseDOMExceptionAndReturnFalse(
+          exceptionState, IndexSizeError, "The input data has zero elements.");
+    }
+
+    if (dataLength % 4) {
+      return RaiseDOMExceptionAndReturnFalse(
+          exceptionState, IndexSizeError,
+          "The input data length is not a multiple of 4.");
+    }
+
+    if ((paramFlags & kParamWidth) && (dataLength / 4) % width) {
+      return RaiseDOMExceptionAndReturnFalse(
+          exceptionState, IndexSizeError,
+          "The input data length is not a multiple of (4 * width).");
+    }
+
+    if ((paramFlags & kParamHeight & kParamWidth) &&
+        height != dataLength / (4 * width))
+      return RaiseDOMExceptionAndReturnFalse(
+          exceptionState, IndexSizeError,
+          "The input data length is not equal to (4 * width * height).");
+  }
+
   if (paramFlags & kParamSize) {
     if (!size->width() || !size->height())
       return false;
@@ -65,132 +130,60 @@
     if (!dataSize.IsValid())
       return false;
     if (paramFlags & kParamData) {
-      DCHECK(data);
-      unsigned length =
-          data->type() == DOMArrayBufferView::ViewType::TypeUint8Clamped
-              ? (const_cast<DOMUint8ClampedArray*>(
-                     static_cast<const DOMUint8ClampedArray*>(data)))
-                    ->length()
-              : (const_cast<DOMFloat32Array*>(
-                     static_cast<const DOMFloat32Array*>(data)))
-                    ->length();
-      if (dataSize.ValueOrDie() > length)
+      if (dataSize.ValueOrDie() > dataLength)
         return false;
     }
-    return true;
   }
 
-  // ImageData::create parameters with ExceptionState
-  if ((paramFlags & kParamWidth) && !width) {
-    exceptionState->throwDOMException(
-        IndexSizeError, "The source width is zero or not a number.");
-    return false;
-  }
-  if ((paramFlags & kParamHeight) && !height) {
-    exceptionState->throwDOMException(
-        IndexSizeError, "The source height is zero or not a number.");
-    return false;
-  }
-  if (paramFlags & (kParamWidth | kParamHeight)) {
-    CheckedNumeric<unsigned> dataSize = 4;
-    dataSize *= width;
-    dataSize *= height;
-    if (!dataSize.IsValid()) {
-      exceptionState->throwDOMException(
-          IndexSizeError,
-          "The requested image size exceeds the supported range.");
-      return false;
-    }
-  }
-  if (paramFlags & kParamData) {
-    DCHECK(data);
-    unsigned length =
-        data->type() == DOMArrayBufferView::ViewType::TypeUint8Clamped
-            ? (const_cast<DOMUint8ClampedArray*>(
-                   static_cast<const DOMUint8ClampedArray*>(data)))
-                  ->length()
-            : (const_cast<DOMFloat32Array*>(
-                   static_cast<const DOMFloat32Array*>(data)))
-                  ->length();
-    if (!length) {
-      exceptionState->throwDOMException(IndexSizeError,
-                                        "The input data has zero elements.");
-      return false;
-    }
-    if (length % 4) {
-      exceptionState->throwDOMException(
-          IndexSizeError, "The input data length is not a multiple of 4.");
-      return false;
-    }
-    length /= 4;
-    if (length % width) {
-      exceptionState->throwDOMException(
-          IndexSizeError,
-          "The input data length is not a multiple of (4 * width).");
-      return false;
-    }
-    if ((paramFlags & kParamHeight) && height != length / width) {
-      exceptionState->throwDOMException(
-          IndexSizeError,
-          "The input data length is not equal to (4 * width * height).");
-      return false;
-    }
-  }
-  if (paramFlags & kParamColorSpace) {
-    if (!colorSpace || colorSpace->length() == 0) {
-      exceptionState->throwDOMException(
-          NotSupportedError, "The source color space is not defined.");
-      return false;
-    }
-    if (imageDataType == kUint8ClampedImageData &&
-        *colorSpace != kLegacyImageDataColorSpaceName &&
-        *colorSpace != kSRGBImageDataColorSpaceName) {
-      exceptionState->throwDOMException(NotSupportedError,
-                                        "The input color space is not "
-                                        "supported in "
-                                        "Uint8ClampedArray-backed ImageData.");
-      return false;
-    }
-    if (imageDataType == kFloat32ImageData &&
-        *colorSpace != kLinearRGBImageDataColorSpaceName) {
-      exceptionState->throwDOMException(NotSupportedError,
-                                        "The input color space is not "
-                                        "supported in "
-                                        "Float32Array-backed ImageData.");
-      return false;
-    }
-  }
   return true;
 }
 
-DOMUint8ClampedArray* ImageData::allocateAndValidateUint8ClampedArray(
+DOMArrayBufferView* ImageData::allocateAndValidateDataArray(
     const unsigned& length,
+    ImageDataStorageFormat storageFormat,
     ExceptionState* exceptionState) {
   if (!length)
     return nullptr;
-  DOMUint8ClampedArray* dataArray = DOMUint8ClampedArray::createOrNull(length);
-  if (!dataArray || length != dataArray->length()) {
-    if (exceptionState) {
+
+  DOMArrayBufferView* dataArray = nullptr;
+  unsigned dataLength = 0;
+  switch (storageFormat) {
+    case kUint8ClampedArrayStorageFormat:
+      dataArray = DOMUint8ClampedArray::createOrNull(length);
+      dataLength = dataArray->view()->byteLength();
+      break;
+    case kUint16ArrayStorageFormat:
+      dataArray = DOMUint16Array::createOrNull(length);
+      dataLength = dataArray->view()->byteLength() / 2;
+      break;
+    case kFloat32ArrayStorageFormat:
+      dataArray = DOMFloat32Array::createOrNull(length);
+      dataLength = dataArray->view()->byteLength() / 4;
+      break;
+    default:
+      NOTREACHED();
+  }
+
+  if (!dataArray || length != dataLength) {
+    if (exceptionState)
       exceptionState->throwDOMException(V8RangeError,
                                         "Out of memory at ImageData creation");
-    }
     return nullptr;
   }
+
   return dataArray;
 }
 
 ImageData* ImageData::create(const IntSize& size) {
   if (!ImageData::validateConstructorArguments(kParamSize, &size))
     return nullptr;
-  DOMUint8ClampedArray* byteArray =
-      ImageData::allocateAndValidateUint8ClampedArray(4 * size.width() *
-                                                      size.height());
-  if (!byteArray)
-    return nullptr;
+  DOMArrayBufferView* byteArray = allocateAndValidateDataArray(
+      4 * size.width() * size.height(), kUint8ClampedArrayStorageFormat);
   return new ImageData(size, byteArray);
 }
 
-// This function accepts size (0, 0).
+// This function accepts size (0, 0) and always returns the ImageData in
+// "srgb" color space and "uint8" storage format.
 ImageData* ImageData::createForTest(const IntSize& size) {
   CheckedNumeric<unsigned> dataSize = 4;
   dataSize *= size.width();
@@ -211,17 +204,8 @@
   if (!ImageData::validateConstructorArguments(kParamSize | kParamData, &size,
                                                0, 0, byteArray))
     return nullptr;
-  return new ImageData(size, byteArray);
-}
 
-ImageData* ImageData::create(const IntSize& size,
-                             DOMUint8ClampedArray* byteArray,
-                             const String& colorSpace) {
-  if (!ImageData::validateConstructorArguments(
-          kParamSize | kParamData | kParamColorSpace, &size, 0, 0, byteArray,
-          &colorSpace))
-    return nullptr;
-  return new ImageData(size, byteArray, colorSpace);
+  return new ImageData(size, byteArray);
 }
 
 ImageData* ImageData::create(unsigned width,
@@ -229,21 +213,21 @@
                              ExceptionState& exceptionState) {
   if (!ImageData::validateConstructorArguments(kParamWidth | kParamHeight,
                                                nullptr, width, height, nullptr,
-                                               nullptr, &exceptionState))
+                                               &exceptionState))
     return nullptr;
-  DOMUint8ClampedArray* byteArray =
-      ImageData::allocateAndValidateUint8ClampedArray(4 * width * height,
-                                                      &exceptionState);
+
+  DOMArrayBufferView* byteArray = allocateAndValidateDataArray(
+      4 * width * height, kUint8ClampedArrayStorageFormat, &exceptionState);
   return byteArray ? new ImageData(IntSize(width, height), byteArray) : nullptr;
 }
 
 ImageData* ImageData::create(DOMUint8ClampedArray* data,
                              unsigned width,
                              ExceptionState& exceptionState) {
-  if (!ImageData::validateConstructorArguments(kParamData | kParamWidth,
-                                               nullptr, width, 0, data, nullptr,
-                                               &exceptionState))
+  if (!ImageData::validateConstructorArguments(
+          kParamData | kParamWidth, nullptr, width, 0, data, &exceptionState))
     return nullptr;
+
   unsigned height = data->length() / (width * 4);
   return new ImageData(IntSize(width, height), data);
 }
@@ -254,50 +238,55 @@
                              ExceptionState& exceptionState) {
   if (!ImageData::validateConstructorArguments(
           kParamData | kParamWidth | kParamHeight, nullptr, width, height, data,
-          nullptr, &exceptionState))
+          &exceptionState))
     return nullptr;
+
   return new ImageData(IntSize(width, height), data);
 }
 
-ImageData* ImageData::createImageData(unsigned width,
-                                      unsigned height,
-                                      String colorSpace,
-                                      ExceptionState& exceptionState) {
-  if (!ImageData::validateConstructorArguments(
-          kParamWidth | kParamHeight | kParamColorSpace, nullptr, width, height,
-          nullptr, &colorSpace, &exceptionState))
+ImageData* ImageData::createImageData(
+    unsigned width,
+    unsigned height,
+    const ImageDataColorSettings& colorSettings,
+    ExceptionState& exceptionState) {
+  if (!ImageData::validateConstructorArguments(kParamWidth | kParamHeight,
+                                               nullptr, width, height, nullptr,
+                                               &exceptionState))
     return nullptr;
 
-  DOMUint8ClampedArray* byteArray =
-      ImageData::allocateAndValidateUint8ClampedArray(4 * width * height,
-                                                      &exceptionState);
-  return byteArray
-             ? new ImageData(IntSize(width, height), byteArray, colorSpace)
-             : nullptr;
+  ImageDataStorageFormat storageFormat =
+      ImageData::getImageDataStorageFormat(colorSettings.storageFormat());
+  DOMArrayBufferView* bufferView = allocateAndValidateDataArray(
+      4 * width * height, storageFormat, &exceptionState);
+
+  if (!bufferView)
+    return nullptr;
+
+  return new ImageData(IntSize(width, height), bufferView, &colorSettings);
 }
 
-ImageData* ImageData::createImageData(DOMUint8ClampedArray* data,
-                                      unsigned width,
-                                      String colorSpace,
-                                      ExceptionState& exceptionState) {
-  if (!ImageData::validateConstructorArguments(
-          kParamData | kParamWidth | kParamColorSpace, nullptr, width, 0, data,
-          &colorSpace, &exceptionState))
-    return nullptr;
-  unsigned height = data->length() / (width * 4);
-  return new ImageData(IntSize(width, height), data, colorSpace);
-}
+ImageData* ImageData::createImageData(
+    ImageDataArray& data,
+    unsigned width,
+    unsigned height,
+    const ImageDataColorSettings& colorSettings,
+    ExceptionState& exceptionState) {
+  DOMArrayBufferView* bufferView = nullptr;
+  if (data.isUint8ClampedArray())
+    bufferView = data.getAsUint8ClampedArray();
+  else if (data.isUint16Array())
+    bufferView = data.getAsUint16Array();
+  else if (data.isFloat32Array())
+    bufferView = data.getAsFloat32Array();
+  else
+    NOTREACHED();
 
-ImageData* ImageData::createImageData(DOMUint8ClampedArray* data,
-                                      unsigned width,
-                                      unsigned height,
-                                      String colorSpace,
-                                      ExceptionState& exceptionState) {
   if (!ImageData::validateConstructorArguments(
-          kParamData | kParamWidth | kParamHeight | kParamColorSpace, nullptr,
-          width, height, data, &colorSpace, &exceptionState))
+          kParamData | kParamWidth | kParamHeight, nullptr, width, height,
+          bufferView, &exceptionState))
     return nullptr;
-  return new ImageData(IntSize(width, height), data, colorSpace);
+
+  return new ImageData(IntSize(width, height), bufferView, &colorSettings);
 }
 
 ScriptPromise ImageData::createImageBitmap(ScriptState* scriptState,
@@ -330,7 +319,7 @@
   wrapper =
       ScriptWrappable::associateWithWrapper(isolate, wrapperType, wrapper);
 
-  if (!wrapper.IsEmpty() && m_data.get()) {
+  if (!wrapper.IsEmpty() && m_data) {
     // Create a V8 Uint8ClampedArray object and set the "data" property
     // of the ImageData object to the created v8 object, eliminating the
     // C++ callback when accessing the "data" property.
@@ -344,61 +333,95 @@
   return wrapper;
 }
 
-ImageDataColorSpace ImageData::getImageDataColorSpace(String colorSpaceName) {
-  if (colorSpaceName == kLegacyImageDataColorSpaceName)
-    return kLegacyImageDataColorSpace;
-  if (colorSpaceName == kSRGBImageDataColorSpaceName)
-    return kSRGBImageDataColorSpace;
-  if (colorSpaceName == kLinearRGBImageDataColorSpaceName)
-    return kLinearRGBImageDataColorSpace;
-  NOTREACHED();
-  return kLegacyImageDataColorSpace;
-}
-
-String ImageData::getImageDataColorSpaceName(ImageDataColorSpace colorSpace) {
-  switch (colorSpace) {
-    case kLegacyImageDataColorSpace:
-      return kLegacyImageDataColorSpaceName;
-    case kSRGBImageDataColorSpace:
-      return kSRGBImageDataColorSpaceName;
-    case kLinearRGBImageDataColorSpace:
-      return kLinearRGBImageDataColorSpaceName;
-  }
-  NOTREACHED();
-  return String();
-}
-
-sk_sp<SkColorSpace> ImageData::imageDataColorSpaceToSkColorSpace(
-    ImageDataColorSpace colorSpace) {
-  switch (colorSpace) {
-    case kLegacyImageDataColorSpace:
-      return ColorBehavior::globalTargetColorSpace().ToSkColorSpace();
-    case kSRGBImageDataColorSpace:
-      return SkColorSpace::MakeSRGB();
-    case kLinearRGBImageDataColorSpace:
-      return SkColorSpace::MakeSRGBLinear();
-  }
-  NOTREACHED();
+const DOMUint8ClampedArray* ImageData::data() const {
+  if (m_colorSettings.storageFormat() == kUint8ClampedArrayStorageFormatName)
+    return m_data.get();
   return nullptr;
 }
 
+DOMUint8ClampedArray* ImageData::data() {
+  if (m_colorSettings.storageFormat() == kUint8ClampedArrayStorageFormatName)
+    return m_data.get();
+  return nullptr;
+}
+
+ImageDataStorageFormat ImageData::getImageDataStorageFormat(
+    const String& storageFormatName) {
+  if (storageFormatName == kUint8ClampedArrayStorageFormatName)
+    return kUint8ClampedArrayStorageFormat;
+  if (storageFormatName == kUint16ArrayStorageFormatName)
+    return kUint16ArrayStorageFormat;
+  if (storageFormatName == kFloat32ArrayStorageFormatName)
+    return kFloat32ArrayStorageFormat;
+  NOTREACHED();
+  return kUint8ClampedArrayStorageFormat;
+}
+
+// For ImageData, the color space is only specified by color settings.
+// It cannot have a SkColorSpace. This doesn't mean anything. Fix this.
 sk_sp<SkColorSpace> ImageData::getSkColorSpace() {
   if (!RuntimeEnabledFeatures::experimentalCanvasFeaturesEnabled() ||
       !RuntimeEnabledFeatures::colorCorrectRenderingEnabled())
     return nullptr;
-  return ImageData::imageDataColorSpaceToSkColorSpace(m_colorSpace);
+
+  return SkColorSpace::MakeSRGB();
+}
+
+void ImageData::trace(Visitor* visitor) {
+  visitor->trace(m_data);
+  visitor->trace(m_dataU16);
+  visitor->trace(m_dataF32);
+  visitor->trace(m_dataUnion);
 }
 
 ImageData::ImageData(const IntSize& size,
-                     DOMUint8ClampedArray* byteArray,
-                     String colorSpaceName)
-    : m_size(size),
-      m_colorSpace(getImageDataColorSpace(colorSpaceName)),
-      m_data(byteArray) {
+                     DOMArrayBufferView* data,
+                     const ImageDataColorSettings* colorSettings)
+    : m_size(size) {
   DCHECK_GE(size.width(), 0);
   DCHECK_GE(size.height(), 0);
-  SECURITY_CHECK(static_cast<unsigned>(size.width() * size.height() * 4) <=
-                 m_data->length());
+  DCHECK(data);
+
+  m_data = nullptr;
+  m_dataU16 = nullptr;
+  m_dataF32 = nullptr;
+
+  if (colorSettings) {
+    m_colorSettings.setColorSpace(colorSettings->colorSpace());
+    m_colorSettings.setStorageFormat(colorSettings->storageFormat());
+  }
+
+  ImageDataStorageFormat storageFormat =
+      getImageDataStorageFormat(m_colorSettings.storageFormat());
+
+  switch (storageFormat) {
+    case kUint8ClampedArrayStorageFormat:
+      m_data = const_cast<DOMUint8ClampedArray*>(
+          static_cast<const DOMUint8ClampedArray*>(data));
+      m_dataUnion.setUint8ClampedArray(m_data);
+      SECURITY_CHECK(static_cast<unsigned>(size.width() * size.height() * 4) <=
+                     m_data->length());
+      break;
+
+    case kUint16ArrayStorageFormat:
+      m_dataU16 =
+          const_cast<DOMUint16Array*>(static_cast<const DOMUint16Array*>(data));
+      m_dataUnion.setUint16Array(m_dataU16);
+      SECURITY_CHECK(static_cast<unsigned>(size.width() * size.height() * 4) <=
+                     m_dataU16->length());
+      break;
+
+    case kFloat32ArrayStorageFormat:
+      m_dataF32 = const_cast<DOMFloat32Array*>(
+          static_cast<const DOMFloat32Array*>(data));
+      m_dataUnion.setFloat32Array(m_dataF32);
+      SECURITY_CHECK(static_cast<unsigned>(size.width() * size.height() * 4) <=
+                     m_dataF32->length());
+      break;
+
+    default:
+      NOTREACHED();
+  }
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/html/ImageData.h b/third_party/WebKit/Source/core/html/ImageData.h
index 246a4cf8..392ad600 100644
--- a/third_party/WebKit/Source/core/html/ImageData.h
+++ b/third_party/WebKit/Source/core/html/ImageData.h
@@ -30,9 +30,11 @@
 #define ImageData_h
 
 #include "bindings/core/v8/ScriptWrappable.h"
+#include "bindings/core/v8/Uint8ClampedArrayOrUint16ArrayOrFloat32Array.h"
 #include "core/CoreExport.h"
-#include "core/dom/DOMArrayBufferView.h"
 #include "core/dom/DOMTypedArray.h"
+#include "core/html/ImageDataColorSettings.h"
+#include "core/html/canvas/CanvasRenderingContext.h"
 #include "core/imagebitmap/ImageBitmapSource.h"
 #include "platform/geometry/IntRect.h"
 #include "platform/geometry/IntSize.h"
@@ -47,28 +49,24 @@
 class ExceptionState;
 class ImageBitmapOptions;
 
+typedef Uint8ClampedArrayOrUint16ArrayOrFloat32Array ImageDataArray;
+
 enum ConstructorParams {
   kParamSize = 1,
   kParamWidth = 1 << 1,
   kParamHeight = 1 << 2,
   kParamData = 1 << 3,
-  kParamColorSpace = 1 << 4,
 };
 
-enum ImageDataType {
-  kUint8ClampedImageData,
-  kFloat32ImageData,
+enum ImageDataStorageFormat {
+  kUint8ClampedArrayStorageFormat,
+  kUint16ArrayStorageFormat,
+  kFloat32ArrayStorageFormat,
 };
 
-enum ImageDataColorSpace {
-  kLegacyImageDataColorSpace,
-  kSRGBImageDataColorSpace,
-  kLinearRGBImageDataColorSpace,
-};
-
-const char* const kLinearRGBImageDataColorSpaceName = "linear-rgb";
-const char* const kSRGBImageDataColorSpaceName = "srgb";
-const char* const kLegacyImageDataColorSpaceName = "legacy-srgb";
+constexpr const char* kUint8ClampedArrayStorageFormatName = "uint8";
+constexpr const char* kUint16ArrayStorageFormatName = "uint16";
+constexpr const char* kFloat32ArrayStorageFormatName = "float32";
 
 class CORE_EXPORT ImageData final : public GarbageCollectedFinalized<ImageData>,
                                     public ScriptWrappable,
@@ -78,9 +76,7 @@
  public:
   static ImageData* create(const IntSize&);
   static ImageData* create(const IntSize&, DOMUint8ClampedArray*);
-  static ImageData* create(const IntSize&,
-                           DOMUint8ClampedArray*,
-                           const String&);
+
   static ImageData* create(unsigned width, unsigned height, ExceptionState&);
   static ImageData* create(DOMUint8ClampedArray*,
                            unsigned width,
@@ -94,30 +90,31 @@
 
   ImageData* createImageData(unsigned width,
                              unsigned height,
-                             String colorSpace,
+                             const ImageDataColorSettings&,
                              ExceptionState&);
-  ImageData* createImageData(DOMUint8ClampedArray*,
-                             unsigned width,
-                             String colorSpace,
-                             ExceptionState&);
-  ImageData* createImageData(DOMUint8ClampedArray*,
+  ImageData* createImageData(ImageDataArray&,
                              unsigned width,
                              unsigned height,
-                             String colorSpace,
+                             const ImageDataColorSettings&,
                              ExceptionState&);
 
-  static ImageDataColorSpace getImageDataColorSpace(String);
-  static String getImageDataColorSpaceName(ImageDataColorSpace);
-  static sk_sp<SkColorSpace> imageDataColorSpaceToSkColorSpace(
-      ImageDataColorSpace);
+  static ImageDataStorageFormat getImageDataStorageFormat(const String&);
 
   IntSize size() const { return m_size; }
   int width() const { return m_size.width(); }
   int height() const { return m_size.height(); }
-  String colorSpace() const { return getImageDataColorSpaceName(m_colorSpace); }
-  ImageDataColorSpace imageDataColorSpace() { return m_colorSpace; }
-  const DOMUint8ClampedArray* data() const { return m_data.get(); }
-  DOMUint8ClampedArray* data() { return m_data.get(); }
+
+  DOMUint8ClampedArray* data();
+  const DOMUint8ClampedArray* data() const;
+  ImageDataArray& dataUnion() { return m_dataUnion; }
+  const ImageDataArray& dataUnion() const { return m_dataUnion; }
+  void dataUnion(ImageDataArray& result) { result = m_dataUnion; };
+  const ImageDataColorSettings& colorSettings() const {
+    return m_colorSettings;
+  }
+  void colorSettings(ImageDataColorSettings& result) {
+    result = m_colorSettings;
+  };
 
   sk_sp<SkColorSpace> getSkColorSpace();
 
@@ -129,34 +126,35 @@
                                   const ImageBitmapOptions&,
                                   ExceptionState&) override;
 
-  DEFINE_INLINE_TRACE() { visitor->trace(m_data); }
+  void trace(Visitor*);
 
   WARN_UNUSED_RESULT v8::Local<v8::Object> associateWithWrapper(
       v8::Isolate*,
       const WrapperTypeInfo*,
       v8::Local<v8::Object> wrapper) override;
 
-  static bool validateConstructorArguments(
-      const unsigned&,
-      const IntSize* = nullptr,
-      const unsigned& = 0,
-      const unsigned& = 0,
-      const DOMArrayBufferView* = nullptr,
-      const String* = nullptr,
-      ExceptionState* = nullptr,
-      ImageDataType = kUint8ClampedImageData);
+  static bool validateConstructorArguments(const unsigned&,
+                                           const IntSize* = nullptr,
+                                           const unsigned& = 0,
+                                           const unsigned& = 0,
+                                           const DOMArrayBufferView* = nullptr,
+                                           ExceptionState* = nullptr);
 
  private:
   ImageData(const IntSize&,
-            DOMUint8ClampedArray*,
-            String = kLegacyImageDataColorSpaceName);
+            DOMArrayBufferView*,
+            const ImageDataColorSettings* = nullptr);
 
   IntSize m_size;
-  ImageDataColorSpace m_colorSpace;
+  ImageDataColorSettings m_colorSettings;
+  ImageDataArray m_dataUnion;
   Member<DOMUint8ClampedArray> m_data;
+  Member<DOMUint16Array> m_dataU16;
+  Member<DOMFloat32Array> m_dataF32;
 
-  static DOMUint8ClampedArray* allocateAndValidateUint8ClampedArray(
+  static DOMArrayBufferView* allocateAndValidateDataArray(
       const unsigned&,
+      ImageDataStorageFormat,
       ExceptionState* = nullptr);
 };
 
diff --git a/third_party/WebKit/Source/core/html/ImageData.idl b/third_party/WebKit/Source/core/html/ImageData.idl
index 38051b0..58cca55 100644
--- a/third_party/WebKit/Source/core/html/ImageData.idl
+++ b/third_party/WebKit/Source/core/html/ImageData.idl
@@ -29,7 +29,7 @@
 // https://html.spec.whatwg.org/#dom-imagedata
 // https://github.com/junov/CanvasColorSpace/blob/master/CanvasColorSpaceProposal.md#imagedata
 
-enum ImageDataColorSpace { "legacy-srgb", "srgb", "linear-rgb" };
+typedef (Uint8ClampedArray or Uint16Array or Float32Array) ImageDataArray;
 
 [
     Constructor(unsigned long sw, unsigned long sh),
@@ -38,12 +38,18 @@
     RaisesException=Constructor,
 ] interface ImageData {
 
-    [RuntimeEnabled=ExperimentalCanvasFeatures, RaisesException] ImageData createImageData(unsigned long sw, unsigned long sh, ImageDataColorSpace colorSpace);
-    [RuntimeEnabled=ExperimentalCanvasFeatures, RaisesException] ImageData createImageData(Uint8ClampedArray data, unsigned long sw, ImageDataColorSpace colorSpace);
-    [RuntimeEnabled=ExperimentalCanvasFeatures, RaisesException] ImageData createImageData(Uint8ClampedArray data, unsigned long sw, unsigned long sh, ImageDataColorSpace colorSpace);
+    // The following createImageData functions are used instead of the regular constructors
+    // as currently Blink IDL does not allow to put custom constructors behind a flag
+    // (crbug.com/672978). These must be replaced with regular constructor declaration
+    // as specified in the proposal before shipping.
+    // https://github.com/WICG/canvas-color-space/blob/master/CanvasColorSpaceProposal.md
+
+    [RuntimeEnabled=ExperimentalCanvasFeatures, RaisesException] ImageData createImageData(unsigned long sw, unsigned long sh, ImageDataColorSettings imageDataColorSettings);
+    [RuntimeEnabled=ExperimentalCanvasFeatures, RaisesException] ImageData createImageData(ImageDataArray data, unsigned long sw, unsigned long sh, ImageDataColorSettings imageDataColorSettings);
 
     readonly attribute unsigned long width;
     readonly attribute unsigned long height;
     readonly attribute Uint8ClampedArray data;
-    readonly attribute ImageDataColorSpace colorSpace;
+    [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute ImageDataArray dataUnion;
+    [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute ImageDataColorSettings colorSettings;
 };
diff --git a/third_party/WebKit/Source/core/html/ImageDataColorSettings.idl b/third_party/WebKit/Source/core/html/ImageDataColorSettings.idl
new file mode 100644
index 0000000..828808c
--- /dev/null
+++ b/third_party/WebKit/Source/core/html/ImageDataColorSettings.idl
@@ -0,0 +1,16 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// https://github.com/junov/CanvasColorSpace/blob/master/CanvasColorSpaceProposal.md#imageda
+
+enum ImageDataStorageFormat {
+  "uint8", // default
+  "uint16",
+  "float32",
+};
+
+dictionary ImageDataColorSettings {
+  CanvasColorSpace colorSpace = "srgb";
+  ImageDataStorageFormat storageFormat = "uint8";
+};
diff --git a/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.cpp b/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.cpp
index 77bedfa4..5c4ae21a 100644
--- a/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.cpp
+++ b/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.cpp
@@ -31,16 +31,6 @@
 #include "platform/weborigin/SecurityOrigin.h"
 #include "public/platform/Platform.h"
 
-constexpr const char* kLegacyCanvasColorSpaceName = "legacy-srgb";
-constexpr const char* kSRGBCanvasColorSpaceName = "srgb";
-constexpr const char* kRec2020CanvasColorSpaceName = "rec2020";
-constexpr const char* kP3CanvasColorSpaceName = "p3";
-
-constexpr const char* kRGBA8CanvasPixelFormatName = "8-8-8-8";
-constexpr const char* kRGB10A2CanvasPixelFormatName = "10-10-10-2";
-constexpr const char* kRGBA12CanvasPixelFormatName = "12-12-12-12";
-constexpr const char* kF16CanvasPixelFormatName = "float16";
-
 namespace blink {
 
 CanvasRenderingContext::CanvasRenderingContext(
diff --git a/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h b/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h
index 6186c7f..aacbab6 100644
--- a/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h
+++ b/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h
@@ -61,6 +61,16 @@
   kF16CanvasPixelFormat,
 };
 
+constexpr const char* kLegacyCanvasColorSpaceName = "legacy-srgb";
+constexpr const char* kSRGBCanvasColorSpaceName = "srgb";
+constexpr const char* kRec2020CanvasColorSpaceName = "rec2020";
+constexpr const char* kP3CanvasColorSpaceName = "p3";
+
+constexpr const char* kRGBA8CanvasPixelFormatName = "8-8-8-8";
+constexpr const char* kRGB10A2CanvasPixelFormatName = "10-10-10-2";
+constexpr const char* kRGBA12CanvasPixelFormatName = "12-12-12-12";
+constexpr const char* kF16CanvasPixelFormatName = "float16";
+
 class CORE_EXPORT CanvasRenderingContext
     : public GarbageCollectedFinalized<CanvasRenderingContext>,
       public ScriptWrappable,
diff --git a/third_party/WebKit/Source/core/svg/SVGGraphicsElement.cpp b/third_party/WebKit/Source/core/svg/SVGGraphicsElement.cpp
index 4e39e7fb..48e88ce 100644
--- a/third_party/WebKit/Source/core/svg/SVGGraphicsElement.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGGraphicsElement.cpp
@@ -169,20 +169,16 @@
   }
 
   if (attrName == SVGNames::transformAttr) {
-    LayoutObject* object = layoutObject();
-    if (!object)
-      return;
-
-    invalidateSVGPresentationAttributeStyle();
-
     SVGElement::InvalidationGuard invalidationGuard(this);
+    invalidateSVGPresentationAttributeStyle();
     // TODO(fs): The InvalidationGuard will make sure all instances are
     // invalidated, but the style recalc will propagate to instances too. So
     // there is some redundant operations being performed here. Could we get
     // away with removing the InvalidationGuard?
     setNeedsStyleRecalc(LocalStyleChange,
                         StyleChangeReasonForTracing::fromAttribute(attrName));
-    markForLayoutAndParentResourceInvalidation(object);
+    if (LayoutObject* object = layoutObject())
+      markForLayoutAndParentResourceInvalidation(object);
     return;
   }
 
diff --git a/third_party/WebKit/Source/core/svg/SVGSVGElement.cpp b/third_party/WebKit/Source/core/svg/SVGSVGElement.cpp
index eec5eb4..0206083a 100644
--- a/third_party/WebKit/Source/core/svg/SVGSVGElement.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGSVGElement.cpp
@@ -265,7 +265,10 @@
     // to mark it for updating.
     if (widthOrHeightChanged) {
       LayoutObject* layoutObject = this->layoutObject();
-      if (layoutObject && layoutObject->isSVGRoot()) {
+      // If the element is not attached, we cannot be sure if it is (going to
+      // be) an outermost root, so always mark presentation attributes dirty in
+      // that case.
+      if (!layoutObject || layoutObject->isSVGRoot()) {
         invalidateSVGPresentationAttributeStyle();
         setNeedsStyleRecalc(LocalStyleChange,
                             StyleChangeReasonForTracing::create(
diff --git a/third_party/WebKit/Source/modules/mediastream/MediaTrackSettings.idl b/third_party/WebKit/Source/modules/mediastream/MediaTrackSettings.idl
index f0121fa9..1d5c05f 100644
--- a/third_party/WebKit/Source/modules/mediastream/MediaTrackSettings.idl
+++ b/third_party/WebKit/Source/modules/mediastream/MediaTrackSettings.idl
@@ -7,17 +7,22 @@
 dictionary MediaTrackSettings {
     long width;
     long height;
-    double aspectRatio;
+    // aspectRatio is not implemented.
+    // double aspectRatio;
     double frameRate;
     DOMString facingMode;
-    double volume;
-    long sampleRate;
-    long sampleSize;
-    boolean echoCancellation;
-    double latency;
-    long channelCount;
+    // volume, sampleRate and sampleSize are not implemented.
+    // double volume;
+    // long sampleRate;
+    // long sampleSize;
+    // echoCancellation is not implemented: crbug.com/682245
+    // boolean echoCancellation;
+    // latency and channelCount are not implemented.
+    // double latency;
+    // long channelCount;
     DOMString deviceId;
-    DOMString groupId;
+    // groupId is not implemented.
+    // DOMString groupId;
     // Media Capture Depth Stream Extensions
     // https://w3c.github.io/mediacapture-depth/#mediatracksettings-dictionary
     // TODO(aleksandar.stojiljkovic): videoKind, depthNear, depthFar,
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index a87eb33..3670e9d20 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -46677,6 +46677,15 @@
   </summary>
 </histogram>
 
+<histogram name="PasswordManager.HttpPasswordMigrationMode"
+    enum="HttpPasswordMigrationMode">
+  <owner>jdoerrie@chromium.org</owner>
+  <summary>
+    The mode of migration applied to HTTP passwords migrating to HTTPS. Recorded
+    on HTTPS password form load when there are no credentials saved.
+  </summary>
+</histogram>
+
 <histogram name="PasswordManager.ImportedPasswordsPerUserInCSV">
   <owner>xunlu@chromium.org</owner>
   <owner>vabr@chromium.org</owner>
@@ -96161,6 +96170,15 @@
   <int value="7" label="HEADER_HTTP_09_ON_REUSED_SOCKET"/>
 </enum>
 
+<enum name="HttpPasswordMigrationMode" type="int">
+  <int value="0" label="Moved">
+    HTTP credentials were moved during migration to HTTPS
+  </int>
+  <int value="1" label="Copied">
+    HTTP credentials were copied during migration to HTTPS
+  </int>
+</enum>
+
 <enum name="HttpPipelineStatus" type="int">
   <int value="0" label="Success"/>
   <int value="1" label="Redirected"/>
diff --git a/tools/perf/benchmarks/battor.py b/tools/perf/benchmarks/battor.py
index 49ff8c13..b85e94ea 100644
--- a/tools/perf/benchmarks/battor.py
+++ b/tools/perf/benchmarks/battor.py
@@ -41,6 +41,7 @@
 # crbug.com/565180: Only include cases that report time_to_play
 # Taken directly from media benchmark.
 @benchmark.Disabled('android', 'win8')
+@benchmark.Owner(emails=['charliea@chromium.org'])
 class BattOrToughVideoCases(_BattOrBenchmark):
   """Obtains media metrics for key user scenarios."""
   page_set = page_sets.ToughVideoCasesPageSet
@@ -51,6 +52,7 @@
 
 
 @benchmark.Enabled('mac')
+@benchmark.Owner(emails=['charliea@chromium.org'])
 class BattOrTrivialPages(_BattOrBenchmark):
 
   def CreateStorySet(self, options):
@@ -62,6 +64,7 @@
     return 'battor.trivial_pages'
 
 @benchmark.Enabled('mac')
+@benchmark.Owner(emails=['charliea@chromium.org'])
 class BattOrSteadyStatePages(_BattOrBenchmark):
 
   def CreateStorySet(self, options):
diff --git a/tools/perf/benchmarks/blink_perf.py b/tools/perf/benchmarks/blink_perf.py
index 9fb9e09..1c67684 100644
--- a/tools/perf/benchmarks/blink_perf.py
+++ b/tools/perf/benchmarks/blink_perf.py
@@ -184,6 +184,9 @@
     self.platform.StartLocalServer(pywebsocket_server.PywebsocketServer())
 
 
+@benchmark.Owner(emails=['yukishiino@chromium.org',
+                         'bashi@chromium.org',
+                         'haraken@chromium.org'])
 class BlinkPerfBindings(_BlinkPerfBenchmark):
   tag = 'bindings'
   subdir = 'Bindings'
@@ -203,6 +206,7 @@
   subdir = 'BlinkGC'
 
 
+@benchmark.Owner(emails=['rune@opera.com'])
 class BlinkPerfCSS(_BlinkPerfBenchmark):
   tag = 'css'
   subdir = 'CSS'
@@ -211,6 +215,7 @@
 @benchmark.Disabled('android', # http://crbug.com/685320
                     'android-webview', # http://crbug.com/593200
                     'reference')  # http://crbug.com/576779
+@benchmark.Owner(emails=['junov@chromium.org'])
 class BlinkPerfCanvas(_BlinkPerfBenchmark):
   tag = 'canvas'
   subdir = 'Canvas'
@@ -232,17 +237,22 @@
     return story_set
 
 
+@benchmark.Owner(emails=['yukishiino@chromium.org',
+                         'bashi@chromium.org',
+                         'haraken@chromium.org'])
 class BlinkPerfDOM(_BlinkPerfBenchmark):
   tag = 'dom'
   subdir = 'DOM'
 
 
+@benchmark.Owner(emails=['hayato@chromium.org'])
 class BlinkPerfEvents(_BlinkPerfBenchmark):
   tag = 'events'
   subdir = 'Events'
 
 
 @benchmark.Disabled('win8')  # http://crbug.com/462350
+@benchmark.Owner(emails=['eae@chromium.org'])
 class BlinkPerfLayout(_BlinkPerfBenchmark):
   tag = 'layout'
   subdir = 'Layout'
@@ -252,6 +262,7 @@
     return cls.IsSvelte(possible_browser)  # http://crbug.com/551950
 
 
+@benchmark.Owner(emails=['wangxianzhu@chromium.org'])
 class BlinkPerfPaint(_BlinkPerfBenchmark):
   test = _BlinkPerfPaintMeasurement
   tag = 'paint'
@@ -263,16 +274,21 @@
 
 
 @benchmark.Disabled('win')  # crbug.com/488493
+@benchmark.Owner(emails=['yukishiino@chromium.org',
+                         'bashi@chromium.org',
+                         'haraken@chromium.org'])
 class BlinkPerfParser(_BlinkPerfBenchmark):
   tag = 'parser'
   subdir = 'Parser'
 
 
+@benchmark.Owner(emails=['kouhei@chromium.org', 'fs@opera.com'])
 class BlinkPerfSVG(_BlinkPerfBenchmark):
   tag = 'svg'
   subdir = 'SVG'
 
 
+@benchmark.Owner(emails=['hayato@chromium.org'])
 class BlinkPerfShadowDOM(_BlinkPerfBenchmark):
   tag = 'shadow_dom'
   subdir = 'ShadowDOM'
@@ -280,6 +296,7 @@
 
 # This benchmark is for local testing, doesn't need to run on bots.
 @benchmark.Disabled('all')
+@benchmark.Owner(emails=['tyoshino@chromium.org', 'hiroshige@chromium.org'])
 class BlinkPerfXMLHttpRequest(_BlinkPerfBenchmark):
   tag = 'xml_http_request'
   subdir = 'XMLHttpRequest'
@@ -289,6 +306,7 @@
 #@benchmark.Disabled('win', 'chromeos')
 # Disabling on remaining platforms due to heavy flake https://crbug.com/646938
 @benchmark.Disabled('all')
+@benchmark.Owner(emails=['tyoshino@chromium.org', 'yhirano@chromium.org'])
 class BlinkPerfPywebsocket(_BlinkPerfBenchmark):
   """The blink_perf.pywebsocket tests measure turn-around-time of 10MB
   send/receive for XHR, Fetch API and WebSocket. We might ignore < 10%
diff --git a/tools/perf/benchmarks/dromaeo.py b/tools/perf/benchmarks/dromaeo.py
index 2eaaca3..86be999 100644
--- a/tools/perf/benchmarks/dromaeo.py
+++ b/tools/perf/benchmarks/dromaeo.py
@@ -125,6 +125,9 @@
     return ps
 
 
+@benchmark.Owner(emails=['yukishiino@chromium.org',
+                         'bashi@chromium.org',
+                         'haraken@chromium.org'])
 class DromaeoDomCoreAttr(_DromaeoBenchmark):
   """Dromaeo DOMCore attr JavaScript benchmark.
 
@@ -138,6 +141,9 @@
     return 'dromaeo.domcoreattr'
 
 
+@benchmark.Owner(emails=['yukishiino@chromium.org',
+                         'bashi@chromium.org',
+                         'haraken@chromium.org'])
 class DromaeoDomCoreModify(_DromaeoBenchmark):
   """Dromaeo DOMCore modify JavaScript benchmark.
 
@@ -151,6 +157,9 @@
     return 'dromaeo.domcoremodify'
 
 
+@benchmark.Owner(emails=['yukishiino@chromium.org',
+                         'bashi@chromium.org',
+                         'haraken@chromium.org'])
 class DromaeoDomCoreQuery(_DromaeoBenchmark):
   """Dromaeo DOMCore query JavaScript benchmark.
 
@@ -164,6 +173,9 @@
     return 'dromaeo.domcorequery'
 
 
+@benchmark.Owner(emails=['yukishiino@chromium.org',
+                         'bashi@chromium.org',
+                         'haraken@chromium.org'])
 class DromaeoDomCoreTraverse(_DromaeoBenchmark):
   """Dromaeo DOMCore traverse JavaScript benchmark.
 
@@ -177,6 +189,9 @@
     return 'dromaeo.domcoretraverse'
 
 
+@benchmark.Owner(emails=['yukishiino@chromium.org',
+                         'bashi@chromium.org',
+                         'haraken@chromium.org'])
 class DromaeoJslibAttrJquery(_DromaeoBenchmark):
   """Dromaeo JSLib attr jquery JavaScript benchmark.
 
@@ -195,6 +210,9 @@
     # http://crbug.com/634055 (Android One).
     return cls.IsSvelte(possible_browser)
 
+@benchmark.Owner(emails=['yukishiino@chromium.org',
+                         'bashi@chromium.org',
+                         'haraken@chromium.org'])
 class DromaeoJslibAttrPrototype(_DromaeoBenchmark):
   """Dromaeo JSLib attr prototype JavaScript benchmark.
 
@@ -209,6 +227,9 @@
     return 'dromaeo.jslibattrprototype'
 
 
+@benchmark.Owner(emails=['yukishiino@chromium.org',
+                         'bashi@chromium.org',
+                         'haraken@chromium.org'])
 class DromaeoJslibEventJquery(_DromaeoBenchmark):
   """Dromaeo JSLib event jquery JavaScript benchmark.
 
@@ -223,6 +244,9 @@
     return 'dromaeo.jslibeventjquery'
 
 
+@benchmark.Owner(emails=['yukishiino@chromium.org',
+                         'bashi@chromium.org',
+                         'haraken@chromium.org'])
 class DromaeoJslibEventPrototype(_DromaeoBenchmark):
   """Dromaeo JSLib event prototype JavaScript benchmark.
 
@@ -241,6 +265,9 @@
 # android: http://crbug.com/503138
 # linux: http://crbug.com/583075
 @benchmark.Disabled('win-reference', 'android', 'linux')
+@benchmark.Owner(emails=['yukishiino@chromium.org',
+                         'bashi@chromium.org',
+                         'haraken@chromium.org'])
 class DromaeoJslibModifyJquery(_DromaeoBenchmark):
   """Dromaeo JSLib modify jquery JavaScript benchmark.
 
@@ -255,6 +282,9 @@
     return 'dromaeo.jslibmodifyjquery'
 
 
+@benchmark.Owner(emails=['yukishiino@chromium.org',
+                         'bashi@chromium.org',
+                         'haraken@chromium.org'])
 class DromaeoJslibModifyPrototype(_DromaeoBenchmark):
   """Dromaeo JSLib modify prototype JavaScript benchmark.
 
@@ -269,6 +299,9 @@
     return 'dromaeo.jslibmodifyprototype'
 
 
+@benchmark.Owner(emails=['yukishiino@chromium.org',
+                         'bashi@chromium.org',
+                         'haraken@chromium.org'])
 class DromaeoJslibStyleJquery(_DromaeoBenchmark):
   """Dromaeo JSLib style jquery JavaScript benchmark.
 
@@ -283,6 +316,9 @@
     return 'dromaeo.jslibstylejquery'
 
 
+@benchmark.Owner(emails=['yukishiino@chromium.org',
+                         'bashi@chromium.org',
+                         'haraken@chromium.org'])
 class DromaeoJslibStylePrototype(_DromaeoBenchmark):
   """Dromaeo JSLib style prototype JavaScript benchmark.
 
@@ -297,6 +333,9 @@
     return 'dromaeo.jslibstyleprototype'
 
 
+@benchmark.Owner(emails=['yukishiino@chromium.org',
+                         'bashi@chromium.org',
+                         'haraken@chromium.org'])
 class DromaeoJslibTraverseJquery(_DromaeoBenchmark):
   """Dromaeo JSLib traverse jquery JavaScript benchmark.
 
@@ -312,6 +351,9 @@
     return 'dromaeo.jslibtraversejquery'
 
 
+@benchmark.Owner(emails=['yukishiino@chromium.org',
+                         'bashi@chromium.org',
+                         'haraken@chromium.org'])
 class DromaeoJslibTraversePrototype(_DromaeoBenchmark):
   """Dromaeo JSLib traverse prototype JavaScript benchmark.
 
@@ -325,6 +367,9 @@
     return 'dromaeo.jslibtraverseprototype'
 
 
+@benchmark.Owner(emails=['yukishiino@chromium.org',
+                         'bashi@chromium.org',
+                         'haraken@chromium.org'])
 class DromaeoCSSQueryJquery(_DromaeoBenchmark):
   """Dromaeo CSS Query jquery JavaScript benchmark.
 
diff --git a/tools/perf/benchmarks/image_decoding.py b/tools/perf/benchmarks/image_decoding.py
index 60b23a96..c1681f3 100644
--- a/tools/perf/benchmarks/image_decoding.py
+++ b/tools/perf/benchmarks/image_decoding.py
@@ -3,11 +3,13 @@
 # found in the LICENSE file.
 
 from core import perf_benchmark
+from telemetry import benchmark
 
 from measurements import image_decoding
 import page_sets
 
 
+@benchmark.Owner(emails=['cblume@chromium.org', 'reveman@chromium.org'])
 class ImageDecodingToughImageCases(perf_benchmark.PerfBenchmark):
   test = image_decoding.ImageDecoding
   # TODO: Rename this page set to tough_image_cases.py
diff --git a/tools/perf/benchmarks/indexeddb_perf.py b/tools/perf/benchmarks/indexeddb_perf.py
index 893b0ca..e8799f5 100644
--- a/tools/perf/benchmarks/indexeddb_perf.py
+++ b/tools/perf/benchmarks/indexeddb_perf.py
@@ -89,6 +89,7 @@
 
 
 @benchmark.Disabled('linux') # crbug.com/677972
+@benchmark.Owner(emails=['cmumford@chromium.org'])
 class IndexedDbOriginalSectioned(perf_benchmark.PerfBenchmark):
   """Chromium's IndexedDB Performance tests."""
   test = _IndexedDbMeasurement
@@ -100,6 +101,7 @@
 
 
 @benchmark.Disabled('linux') # crbug.com/677972
+@benchmark.Owner(emails=['cmumford@chromium.org'])
 class IndexedDbTracing(perf_benchmark.PerfBenchmark):
   """IndexedDB Performance tests that use tracing."""
   page_set = page_sets.IndexedDBEndurePageSet
diff --git a/tools/perf/benchmarks/jetstream.py b/tools/perf/benchmarks/jetstream.py
index 1231481..fb30892 100644
--- a/tools/perf/benchmarks/jetstream.py
+++ b/tools/perf/benchmarks/jetstream.py
@@ -77,6 +77,7 @@
 
 
 @benchmark.Disabled('android')
+@benchmark.Owner(emails=['bmeurer@chromium.org', 'mvstanton@chromium.org'])
 class Jetstream(perf_benchmark.PerfBenchmark):
   test = _JetstreamMeasurement
 
diff --git a/tools/perf/benchmarks/jitter.py b/tools/perf/benchmarks/jitter.py
index 206c71b..65baa96 100644
--- a/tools/perf/benchmarks/jitter.py
+++ b/tools/perf/benchmarks/jitter.py
@@ -4,6 +4,7 @@
 
 from core import perf_benchmark
 
+from telemetry import benchmark
 from telemetry.timeline import chrome_trace_category_filter
 from telemetry.web_perf import timeline_based_measurement
 from telemetry.web_perf.metrics import jitter_timeline
@@ -15,6 +16,7 @@
 TIMELINE_REQUIRED_CATEGORY = 'blink.console'
 
 
+@benchmark.Owner(emails=['jaydasika@chromium.org'])
 class Jitter(perf_benchmark.PerfBenchmark):
   """Timeline based measurement benchmark for jitter."""
 
diff --git a/tools/perf/benchmarks/kraken.py b/tools/perf/benchmarks/kraken.py
index 3d90902..1715f62 100644
--- a/tools/perf/benchmarks/kraken.py
+++ b/tools/perf/benchmarks/kraken.py
@@ -9,6 +9,7 @@
 
 from core import perf_benchmark
 
+from telemetry import benchmark
 from telemetry import page as page_module
 from telemetry.page import legacy_page_test
 from telemetry import story
@@ -115,6 +116,7 @@
                     '(http://krakenbenchmark.mozilla.org/)'))
 
 
+@benchmark.Owner(emails=['bmeurer@chromium.org', 'mvstanton@chromium.org'])
 class Kraken(perf_benchmark.PerfBenchmark):
   """Mozilla's Kraken JavaScript benchmark.
 
diff --git a/tools/perf/benchmarks/loading.py b/tools/perf/benchmarks/loading.py
index 167f4eb..7dd52ea 100644
--- a/tools/perf/benchmarks/loading.py
+++ b/tools/perf/benchmarks/loading.py
@@ -14,6 +14,7 @@
 
 
 @benchmark.Enabled('android')
+@benchmark.Owner(emails=['kouhei@chromium.org', 'ksakamoto@chromium.org'])
 class LoadingMobile(perf_benchmark.PerfBenchmark):
   """ A benchmark measuring loading performance of mobile sites. """
 
diff --git a/tools/perf/benchmarks/media.py b/tools/perf/benchmarks/media.py
index c5c6ba6..7eb9ae9d 100644
--- a/tools/perf/benchmarks/media.py
+++ b/tools/perf/benchmarks/media.py
@@ -52,6 +52,7 @@
 
 # crbug.com/565180: Only include cases that don't report time_to_play
 @benchmark.Disabled('android')
+@benchmark.Owner(emails=['crouleau@chromium.org', 'videostack-eng@google.com'])
 class MediaExtra(perf_benchmark.PerfBenchmark):
   """Obtains extra media metrics for key user scenarios."""
   test = media.Media
@@ -63,6 +64,7 @@
 
 
 @benchmark.Disabled('android', 'mac')
+@benchmark.Owner(emails=['crouleau@chromium.org', 'videostack-eng@google.com'])
 class MediaNetworkSimulation(perf_benchmark.PerfBenchmark):
   """Obtains media metrics under different network simulations."""
   test = media.Media
@@ -130,6 +132,7 @@
 
 
 @benchmark.Disabled('android-webview')  # crbug.com/419689
+@benchmark.Owner(emails=['crouleau@chromium.org', 'videostack-eng@google.com'])
 class MediaSourceExtensions(perf_benchmark.PerfBenchmark):
   """Obtains media metrics for key media source extensions functions."""
   test = _MSEMeasurement
diff --git a/tools/perf/benchmarks/memory.py b/tools/perf/benchmarks/memory.py
index d669a12..eb7baa0 100644
--- a/tools/perf/benchmarks/memory.py
+++ b/tools/perf/benchmarks/memory.py
@@ -52,6 +52,7 @@
 
 
 @benchmark.Enabled('android')  # catapult:#3176
+@benchmark.Owner(emails=['perezju@chromium.org'])
 class MemoryBenchmarkTop10Mobile(_MemoryInfra):
   """Measure foreground/background memory on top 10 mobile page set.
 
@@ -77,6 +78,7 @@
 
 
 @benchmark.Enabled('android')  # catapult:#3176
+@benchmark.Owner(emails=['perezju@chromium.org'])
 class MemoryBenchmarkTop10MobileStress(MemoryBenchmarkTop10Mobile):
   """Run top 10 mobile page set without closing/restarting the browser.
 
@@ -96,6 +98,7 @@
 
 # Benchmark disabled by default. Force to run with --also-run-disabled-tests.
 @benchmark.Disabled('all')
+@benchmark.Owner(emails=['perezju@chromium.org'])
 class DualBrowserBenchmark(_MemoryInfra):
   """Measures memory usage while interacting with two different browsers.
 
@@ -123,6 +126,7 @@
 
 # Benchmark disabled by default. Force to run with --also-run-disabled-tests.
 @benchmark.Disabled('all')
+@benchmark.Owner(emails=['perezju@chromium.org'])
 class LongRunningDualBrowserBenchmark(_MemoryInfra):
   """Measures memory during prolonged usage of alternating browsers.
 
@@ -152,6 +156,7 @@
 
 
 @benchmark.Enabled('android')  # catapult:#3176
+@benchmark.Owner(emails=['bashi@chromium.org'])
 class RendererMemoryBlinkMemoryMobile(_MemoryInfra):
   """Timeline based benchmark for measuring memory consumption on mobile
   sites on which blink's memory consumption is relatively high.
@@ -216,6 +221,7 @@
     return 'v8' in value.name
 
 
+@benchmark.Owner(emails=['ulan@chromium.org'])
 class MemoryLongRunningIdleGmail(_MemoryV8Benchmark):
   """Use (recorded) real world web sites and measure memory consumption
   of long running idle Gmail page """
@@ -234,6 +240,7 @@
 
 
 @benchmark.Enabled('has tabs')  # http://crbug.com/612210
+@benchmark.Owner(emails=['ulan@chromium.org'])
 class MemoryLongRunningIdleGmailBackground(_MemoryV8Benchmark):
   """Use (recorded) real world web sites and measure memory consumption
   of long running idle Gmail page """
diff --git a/tools/perf/benchmarks/octane.py b/tools/perf/benchmarks/octane.py
index 95b6894..6245c334 100644
--- a/tools/perf/benchmarks/octane.py
+++ b/tools/perf/benchmarks/octane.py
@@ -15,6 +15,7 @@
 
 from core import perf_benchmark
 
+from telemetry import benchmark
 from telemetry import page as page_module
 from telemetry.page import legacy_page_test
 from telemetry import story
@@ -131,6 +132,7 @@
                            'benchmark collection.'))
 
 
+@benchmark.Owner(emails=['bmeurer@chromium.org', 'mvstanton@chromium.org'])
 class Octane(perf_benchmark.PerfBenchmark):
   """Google's Octane JavaScript benchmark.
 
diff --git a/tools/perf/benchmarks/oilpan_gc_times.py b/tools/perf/benchmarks/oilpan_gc_times.py
index b2b6d4a6..91711d5 100644
--- a/tools/perf/benchmarks/oilpan_gc_times.py
+++ b/tools/perf/benchmarks/oilpan_gc_times.py
@@ -28,6 +28,7 @@
 
 
 @benchmark.Disabled('android')  # crbug.com/589567
+@benchmark.Owner(emails=['peria@chromium.org'])
 class OilpanGCTimesSmoothnessAnimation(perf_benchmark.PerfBenchmark):
   test = oilpan_gc_times.OilpanGCTimesForSmoothness
   page_set = page_sets.ToughAnimationCasesPageSet
diff --git a/tools/perf/benchmarks/page_cycler_v2.py b/tools/perf/benchmarks/page_cycler_v2.py
index 49b5077a..6df6021a 100644
--- a/tools/perf/benchmarks/page_cycler_v2.py
+++ b/tools/perf/benchmarks/page_cycler_v2.py
@@ -64,6 +64,7 @@
 
 @benchmark.Disabled('win10')
 @benchmark.Disabled('android')  # crbug.com/654217
+@benchmark.Owner(emails=['kouhei@chromium.org', 'ksakamoto@chromium.org'])
 class PageCyclerV2Typical25(_PageCyclerV2):
   """Page load time benchmark for a 25 typical web pages.
 
@@ -81,6 +82,7 @@
           cache_temperature.PCV1_COLD, cache_temperature.PCV1_WARM])
 
 
+@benchmark.Owner(emails=['kouhei@chromium.org', 'ksakamoto@chromium.org'])
 class PageCyclerV2IntlArFaHe(_PageCyclerV2):
   """Page load time for a variety of pages in Arabic, Farsi and Hebrew.
 
@@ -97,6 +99,7 @@
           cache_temperature.PCV1_COLD, cache_temperature.PCV1_WARM])
 
 
+@benchmark.Owner(emails=['kouhei@chromium.org', 'ksakamoto@chromium.org'])
 class PageCyclerV2IntlEsFrPtBr(_PageCyclerV2):
   """Page load time for a pages in Spanish, French and Brazilian Portuguese.
 
@@ -113,6 +116,7 @@
           cache_temperature.PCV1_COLD, cache_temperature.PCV1_WARM])
 
 
+@benchmark.Owner(emails=['kouhei@chromium.org', 'ksakamoto@chromium.org'])
 class PageCyclerV2IntlHiRu(_PageCyclerV2):
   """Page load time benchmark for a variety of pages in Hindi and Russian.
 
@@ -130,6 +134,7 @@
 
 
 @benchmark.Disabled('android')  # crbug.com/666898
+@benchmark.Owner(emails=['kouhei@chromium.org', 'ksakamoto@chromium.org'])
 class PageCyclerV2IntlJaZh(_PageCyclerV2):
   """Page load time benchmark for a variety of pages in Japanese and Chinese.
 
@@ -145,6 +150,7 @@
           cache_temperature.PCV1_COLD, cache_temperature.PCV1_WARM])
 
 
+@benchmark.Owner(emails=['kouhei@chromium.org', 'ksakamoto@chromium.org'])
 class PageCyclerV2IntlKoThVi(_PageCyclerV2):
   """Page load time for a variety of pages in Korean, Thai and Vietnamese.
 
@@ -162,6 +168,7 @@
 
 
 @benchmark.Enabled('android')
+@benchmark.Owner(emails=['kouhei@chromium.org', 'ksakamoto@chromium.org'])
 class PageCyclerV2Top10Mobile(_PageCyclerV2):
   """Page load time benchmark for the top 10 mobile web pages.
 
@@ -178,6 +185,7 @@
             cache_temperature.PCV1_COLD, cache_temperature.PCV1_WARM])
 
 
+@benchmark.Owner(emails=['kouhei@chromium.org', 'ksakamoto@chromium.org'])
 class PageCyclerV2ToughLayoutCases(_PageCyclerV2):
   """Page loading for the slowest layouts observed in the Alexa top 1 million.
 
@@ -195,6 +203,7 @@
 
 
 @benchmark.Disabled('reference', 'android')
+@benchmark.Owner(emails=['nasko@chromium.org'])
 class PageCyclerV2BasicOopifIsolated(_PageCyclerV2):
   """ A benchmark measuring performance of out-of-process iframes. """
   page_set = page_sets.OopifBasicPageSet
@@ -211,6 +220,7 @@
           cache_temperature.PCV1_COLD, cache_temperature.PCV1_WARM])
 
 @benchmark.Disabled('android')
+@benchmark.Owner(emails=['nasko@chromium.org'])
 class PageCyclerV2BasicOopif(_PageCyclerV2):
   """ A benchmark measuring performance of the out-of-process iframes page
   set, without running in out-of-process iframes mode.. """
diff --git a/tools/perf/benchmarks/power.py b/tools/perf/benchmarks/power.py
index 31507bd..bf8f291e 100644
--- a/tools/perf/benchmarks/power.py
+++ b/tools/perf/benchmarks/power.py
@@ -11,6 +11,7 @@
 
 
 @benchmark.Enabled('android')
+@benchmark.Owner(emails=['perezju@chromium.org'])
 class PowerAndroidAcceptance(perf_benchmark.PerfBenchmark):
   """Android power acceptance test."""
   test = power.Power
@@ -25,6 +26,7 @@
 
 
 @benchmark.Enabled('android')
+@benchmark.Owner(emails=['perezju@chromium.org'])
 class PowerTypical10Mobile(perf_benchmark.PerfBenchmark):
   """Android typical 10 mobile power test."""
   test = power.Power
@@ -52,6 +54,7 @@
 # @benchmark.Enabled('android')
 @benchmark.Disabled('all')
 @benchmark.Disabled('android-webview')  # http://crbug.com/622300
+@benchmark.Owner(emails=['skyostil@chromium.org'])
 class PowerToughAdCases(perf_benchmark.PerfBenchmark):
   """Android power test with tough ad pages."""
   test = power.Power
@@ -196,6 +199,7 @@
 
 
 @benchmark.Enabled('mac')
+@benchmark.Owner(emails=['erikchen@chromium.org'])
 class PowerScrollingTrivialPage(perf_benchmark.PerfBenchmark):
   """Measure power consumption for some very simple pages."""
   test = power.QuiescentPower
diff --git a/tools/perf/benchmarks/rasterize_and_record_micro.py b/tools/perf/benchmarks/rasterize_and_record_micro.py
index 40bb2e6..103b06e0 100644
--- a/tools/perf/benchmarks/rasterize_and_record_micro.py
+++ b/tools/perf/benchmarks/rasterize_and_record_micro.py
@@ -73,6 +73,7 @@
 
 
 @benchmark.Disabled('all') # http://crbug.com/610424
+@benchmark.Owner(emails=['vmpstr@chromium.org'])
 class RasterizeAndRecordMicroKeySilkCases(_RasterizeAndRecordMicro):
   """Measures rasterize and record performance on the silk sites.
 
diff --git a/tools/perf/benchmarks/repaint.py b/tools/perf/benchmarks/repaint.py
index 92cdd52..52270c1c 100644
--- a/tools/perf/benchmarks/repaint.py
+++ b/tools/perf/benchmarks/repaint.py
@@ -45,6 +45,7 @@
 
 
 @benchmark.Disabled('all')
+@benchmark.Owner(emails=['wkorman@chromium.org', 'vmpstr@chromium.org'])
 class RepaintKeyMobileSites(_Repaint):
   """Measures repaint performance on the key mobile sites.
 
@@ -58,6 +59,7 @@
 # crbug.com/502179
 @benchmark.Enabled('android')
 @benchmark.Disabled('all')
+@benchmark.Owner(emails=['wkorman@chromium.org', 'vmpstr@chromium.org'])
 class RepaintGpuRasterizationKeyMobileSites(_Repaint):
   """Measures repaint performance on the key mobile sites with forced GPU
   rasterization.
diff --git a/tools/perf/benchmarks/scheduler.py b/tools/perf/benchmarks/scheduler.py
index d084e1b..08cd700 100644
--- a/tools/perf/benchmarks/scheduler.py
+++ b/tools/perf/benchmarks/scheduler.py
@@ -10,6 +10,7 @@
 
 
 @benchmark.Disabled('reference')  # crbug.com/549428
+@benchmark.Owner(emails=['skyostil@chromium.org', 'brianderson@chromium.org'])
 class SchedulerToughSchedulingCases(perf_benchmark.PerfBenchmark):
   """Measures rendering statistics while interacting with pages that have
   challenging scheduling properties.
diff --git a/tools/perf/benchmarks/service_worker.py b/tools/perf/benchmarks/service_worker.py
index 390bab57..7d5acb9d 100644
--- a/tools/perf/benchmarks/service_worker.py
+++ b/tools/perf/benchmarks/service_worker.py
@@ -158,6 +158,7 @@
           results.current_page, key, value['units'], value['value']))
 
 
+@benchmark.Owner(emails=['horo@chromium.org'])
 class ServiceWorkerPerfTest(perf_benchmark.PerfBenchmark):
   """Performance test of pages using ServiceWorker.
 
@@ -175,6 +176,7 @@
 
 
 @benchmark.Disabled('android-webview')  # http://crbug.com/653924
+@benchmark.Owner(emails=['horo@chromium.org'])
 class ServiceWorkerMicroBenchmarkPerfTest(perf_benchmark.PerfBenchmark):
   """This test is a microbenchmark of service worker.
 
diff --git a/tools/perf/benchmarks/skpicture_printer.py b/tools/perf/benchmarks/skpicture_printer.py
index 38c6bc4..09a844d 100644
--- a/tools/perf/benchmarks/skpicture_printer.py
+++ b/tools/perf/benchmarks/skpicture_printer.py
@@ -26,6 +26,7 @@
 # Disabled because we do not plan on running this SKP benchmark on the perf
 # waterfall any time soon.
 @benchmark.Disabled('all')
+@benchmark.Owner(emails=['rmistry@chromium.org'])
 class SkpicturePrinter(perf_benchmark.PerfBenchmark):
 
   @classmethod
diff --git a/tools/perf/benchmarks/smoothness.py b/tools/perf/benchmarks/smoothness.py
index fe9f50b..733eb12 100644
--- a/tools/perf/benchmarks/smoothness.py
+++ b/tools/perf/benchmarks/smoothness.py
@@ -37,6 +37,7 @@
     return True
 
 
+@benchmark.Owner(emails=['vmiura@chromium.org'])
 class SmoothnessTop25(_Smoothness):
   """Measures rendering statistics while scrolling down the top 25 web pages.
 
@@ -61,6 +62,7 @@
     return False
 
 
+@benchmark.Owner(emails=['senorblanco@chromium.org'])
 class SmoothnessToughFiltersCases(_Smoothness):
   """Measures frame rate and a variety of other statistics.
 
@@ -84,6 +86,7 @@
     return False
 
 
+@benchmark.Owner(emails=['senorblanco@chromium.org'])
 class SmoothnessToughPathRenderingCases(_Smoothness):
   """Tests a selection of pages with SVG and 2D Canvas paths.
 
@@ -96,6 +99,7 @@
 
 
 @benchmark.Disabled('android')  # crbug.com/526901
+@benchmark.Owner(emails=['junov@chromium.org'])
 class SmoothnessToughCanvasCases(_Smoothness):
   """Measures frame rate and a variety of other statistics.
 
@@ -113,6 +117,7 @@
 
 @benchmark.Disabled('android')  # crbug.com/373812
 @benchmark.Disabled('win-reference')  # crbug.com/612810
+@benchmark.Owner(emails=['kbr@chromium.org', 'zmo@chromium.org'])
 class SmoothnessToughWebGLCases(_Smoothness):
   page_set = page_sets.ToughWebglCasesPageSet
 
@@ -123,6 +128,7 @@
 
 @benchmark.Disabled('win') # http://crbug.com/692663
 @benchmark.Disabled('android-webview')  # http://crbug.com/653933
+@benchmark.Owner(emails=['kbr@chromium.org', 'zmo@chromium.org'])
 class SmoothnessMaps(perf_benchmark.PerfBenchmark):
   page_set = page_sets.MapsPageSet
 
@@ -133,6 +139,7 @@
 
 @benchmark.Disabled('android',
                     'mac')     # crbug.com/567802
+@benchmark.Owner(emails=['ssid@chromium.org'])
 class SmoothnessKeyDesktopMoveCases(_Smoothness):
   page_set = page_sets.KeyDesktopMoveCasesPageSet
 
@@ -147,6 +154,7 @@
 
 
 @benchmark.Enabled('android')
+@benchmark.Owner(emails=['vmiura@chromium.org', 'tdresser@chromium.org'])
 class SmoothnessKeyMobileSites(_Smoothness):
   """Measures rendering statistics while scrolling down the key mobile sites.
 
@@ -166,6 +174,7 @@
 @benchmark.Disabled('android')  # crbug.com/589580
 @benchmark.Disabled('android-reference')  # crbug.com/588786
 @benchmark.Disabled('mac')  # crbug.com/563615
+@benchmark.Owner(emails=['alancutter@chromium.org'])
 class SmoothnessToughAnimationCases(_Smoothness):
   test = smoothness.SmoothnessWithRestart
   page_set = page_sets.ToughAnimationCasesPageSet
@@ -182,6 +191,7 @@
 
 
 @benchmark.Enabled('android')
+@benchmark.Owner(emails=['ajuma@chromium.org'])
 class SmoothnessKeySilkCases(_Smoothness):
   """Measures rendering statistics for the key silk cases without GPU
   rasterization.
@@ -203,6 +213,7 @@
 
 
 @benchmark.Enabled('android')
+@benchmark.Owner(emails=['vmiura@chromium.org'])
 class SmoothnessGpuRasterizationTop25(_Smoothness):
   """Measures rendering statistics for the top 25 with GPU rasterization.
   """
@@ -225,6 +236,7 @@
 # Although GPU rasterization is enabled on Mac, it is blacklisted for certain
 # path cases, so it is still valuable to run both the GPU and non-GPU versions
 # of this benchmark on Mac.
+@benchmark.Owner(emails=['senorblanco@chromium.org'])
 class SmoothnessGpuRasterizationToughPathRenderingCases(_Smoothness):
   """Tests a selection of pages with SVG and 2D canvas paths with GPU
   rasterization.
@@ -243,6 +255,7 @@
 # With GPU Raster enabled on Mac, there's no reason to run this benchmark in
 # addition to SmoothnessFiltersCases.
 @benchmark.Disabled('mac')
+@benchmark.Owner(emails=['senorblanco@chromium.org'])
 class SmoothnessGpuRasterizationFiltersCases(_Smoothness):
   """Tests a selection of pages with SVG and CSS filter effects with GPU
   rasterization.
@@ -264,6 +277,7 @@
 
 
 @benchmark.Enabled('android')
+@benchmark.Owner(emails=['tdresser@chromium.org', 'rbyers@chromium.org'])
 class SmoothnessSyncScrollKeyMobileSites(_Smoothness):
   """Measures rendering statistics for the key mobile sites with synchronous
   (main thread) scrolling.
@@ -285,6 +299,7 @@
 
 
 @benchmark.Enabled('android')
+@benchmark.Owner(emails=['vmiura@chromium.org'])
 class SmoothnessSimpleMobilePages(_Smoothness):
   """Measures rendering statistics for simple mobile sites page set.
   """
@@ -296,6 +311,7 @@
 
 
 @benchmark.Disabled('all') # http://crbug.com/631015
+@benchmark.Owner(emails=['bokan@chromium.org'])
 class SmoothnessToughPinchZoomCases(_Smoothness):
   """Measures rendering statistics for pinch-zooming in the tough pinch zoom
   cases.
@@ -316,6 +332,7 @@
 
 
 @benchmark.Enabled('mac')
+@benchmark.Owner(emails=['ericrk@chromium.org'])
 class SmoothnessDesktopToughPinchZoomCases(_Smoothness):
   """Measures rendering statistics for pinch-zooming in the tough pinch zoom
   cases. Uses lower zoom levels customized for desktop limits.
@@ -331,6 +348,7 @@
 # because of http://crbug.com/610021
 # @benchmark.Enabled('android')
 @benchmark.Disabled('all')
+@benchmark.Owner(emails=['ericrk@chromium.org'])
 class SmoothnessGpuRasterizationToughPinchZoomCases(_Smoothness):
   """Measures rendering statistics for pinch-zooming in the tough pinch zoom
   cases with GPU rasterization.
@@ -352,6 +370,7 @@
 
 
 @benchmark.Enabled('android')
+@benchmark.Owner(emails=['vmiura@chromium.org'])
 class SmoothnessGpuRasterizationPolymer(_Smoothness):
   """Measures rendering statistics for the Polymer cases with GPU rasterization.
   """
@@ -366,6 +385,7 @@
     return 'smoothness.gpu_rasterization.polymer'
 
 
+@benchmark.Owner(emails=['reveman@chromium.org'])
 class SmoothnessToughScrollingCases(_Smoothness):
   page_set = page_sets.ToughScrollingCasesPageSet
 
@@ -382,6 +402,7 @@
     return 'smoothness.tough_scrolling_cases'
 
 @benchmark.Disabled('all')  # crbug.com/667489
+@benchmark.Owner(emails=['ericrk@chromium.org'])
 class SmoothnessGpuRasterizationToughScrollingCases(_Smoothness):
   tag = 'gpu_rasterization'
   test = smoothness.Smoothness
@@ -406,6 +427,7 @@
 
 
 @benchmark.Disabled('android')  # http://crbug.com/610015
+@benchmark.Owner(emails=['cblume@chromium.org'])
 class SmoothnessImageDecodingCases(_Smoothness):
   """Measures decoding statistics for jpeg images.
   """
@@ -425,6 +447,7 @@
 
 
 @benchmark.Disabled('android')  # http://crbug.com/513699
+@benchmark.Owner(emails=['cblume@chromium.org'])
 class SmoothnessGpuImageDecodingCases(_Smoothness):
   """Measures decoding statistics for jpeg images with GPU rasterization.
   """
@@ -442,6 +465,7 @@
 
 
 @benchmark.Enabled('android')
+@benchmark.Owner(emails=['picksi@chromium.org'])
 class SmoothnessPathologicalMobileSites(_Smoothness):
   """Measures task execution statistics while scrolling pathological sites.
   """
@@ -459,6 +483,7 @@
     return False
 
 
+@benchmark.Owner(emails=['vmiura@chromium.org'])
 class SmoothnessToughTextureUploadCases(_Smoothness):
   page_set = page_sets.ToughTextureUploadCasesPageSet
 
@@ -467,6 +492,7 @@
     return 'smoothness.tough_texture_upload_cases'
 
 
+@benchmark.Owner(emails=['skyostil@chromium.org'])
 class SmoothnessToughAdCases(_Smoothness):
   """Measures rendering statistics while displaying advertisements."""
   page_set = page_sets.SyntheticToughAdCasesPageSet
@@ -489,6 +515,7 @@
 # http://crbug.com/522619 (mac/win)
 # http://crbug.com/683247 (android/linux)
 @benchmark.Disabled('win', 'mac', 'android', 'linux')
+@benchmark.Owner(emails=['skyostil@chromium.org'])
 class SmoothnessScrollingToughAdCases(_Smoothness):
   """Measures rendering statistics while scrolling advertisements."""
   page_set = page_sets.ScrollingToughAdCasesPageSet
@@ -503,6 +530,7 @@
     return 'smoothness.scrolling_tough_ad_cases'
 
 
+@benchmark.Owner(emails=['skyostil@chromium.org'])
 class SmoothnessToughWebGLAdCases(_Smoothness):
   """Measures rendering statistics while scrolling advertisements."""
   page_set = page_sets.SyntheticToughWebglAdCasesPageSet
diff --git a/tools/perf/benchmarks/spaceport.py b/tools/perf/benchmarks/spaceport.py
index 46f3b39..cd80b078 100644
--- a/tools/perf/benchmarks/spaceport.py
+++ b/tools/perf/benchmarks/spaceport.py
@@ -104,6 +104,7 @@
 # crbug.com/166703: This test frequently times out on Windows.
 @benchmark.Disabled('mac', 'win',
                     'linux', 'android')  # crbug.com/525112
+@benchmark.Owner(emails=['junov@chromium.org'])
 class Spaceport(perf_benchmark.PerfBenchmark):
   """spaceport.io's PerfMarks benchmark.
 
diff --git a/tools/perf/benchmarks/speedometer.py b/tools/perf/benchmarks/speedometer.py
index 5fb3d2f1..26ee23e 100644
--- a/tools/perf/benchmarks/speedometer.py
+++ b/tools/perf/benchmarks/speedometer.py
@@ -22,6 +22,7 @@
 
 from benchmarks import v8_helper
 
+from telemetry import benchmark
 from telemetry import page as page_module
 from telemetry.page import legacy_page_test
 from telemetry import story
@@ -90,6 +91,7 @@
     keychain_metric.KeychainMetric().AddResults(tab, results)
 
 
+@benchmark.Owner(emails=['bmeurer@chromium.org', 'mvstanton@chromium.org'])
 class Speedometer(perf_benchmark.PerfBenchmark):
   test = SpeedometerMeasurement
 
@@ -108,6 +110,7 @@
     return ps
 
 
+@benchmark.Owner(emails=['hablich@chromium.org'])
 class SpeedometerTurbo(Speedometer):
   def SetExtraBrowserOptions(self, options):
     super(SpeedometerTurbo, self).SetExtraBrowserOptions(options)
diff --git a/tools/perf/benchmarks/start_with_url.py b/tools/perf/benchmarks/start_with_url.py
index cb42df9..64804f40 100644
--- a/tools/perf/benchmarks/start_with_url.py
+++ b/tools/perf/benchmarks/start_with_url.py
@@ -33,6 +33,7 @@
 @benchmark.Enabled('has tabs')
 @benchmark.Enabled('android')
 @benchmark.Disabled('chromeos', 'linux', 'mac', 'win')
+@benchmark.Owner(emails=['pasko@chromium.org'])
 class StartWithUrlColdTBM(_StartupPerfBenchmark):
   """Measures time to start Chrome cold with startup URLs."""
 
@@ -57,6 +58,7 @@
 @benchmark.Enabled('android')
 @benchmark.Disabled('android-reference')  # crbug.com/588786
 @benchmark.Disabled('chromeos', 'linux', 'mac', 'win')
+@benchmark.Owner(emails=['pasko@chromium.org'])
 class StartWithUrlWarmTBM(_StartupPerfBenchmark):
   """Measures stimetime to start Chrome warm with startup URLs."""
 
diff --git a/tools/perf/benchmarks/sunspider.py b/tools/perf/benchmarks/sunspider.py
index 888e194..b8abd29 100644
--- a/tools/perf/benchmarks/sunspider.py
+++ b/tools/perf/benchmarks/sunspider.py
@@ -7,6 +7,7 @@
 
 from core import perf_benchmark
 
+from telemetry import benchmark
 from telemetry import page as page_module
 from telemetry.page import legacy_page_test
 from telemetry import story
@@ -126,6 +127,7 @@
                     'in sunspider'))
 
 
+@benchmark.Owner(emails=['bmeurer@chromium.org', 'mvstanton@chromium.org'])
 class Sunspider(perf_benchmark.PerfBenchmark):
   """Apple's SunSpider JavaScript benchmark.
 
diff --git a/tools/perf/benchmarks/system_health.py b/tools/perf/benchmarks/system_health.py
index 2ff51fa7..cf84b15 100644
--- a/tools/perf/benchmarks/system_health.py
+++ b/tools/perf/benchmarks/system_health.py
@@ -59,6 +59,7 @@
     return True
 
 
+@benchmark.Owner(emails=['charliea@chromium.org', 'nednguyen@chromium.org'])
 class DesktopCommonSystemHealth(_CommonSystemHealthBenchmark):
   """Desktop Chrome Energy System Health Benchmark."""
   PLATFORM = 'desktop'
@@ -73,6 +74,7 @@
 
 
 @benchmark.Enabled('android')
+@benchmark.Owner(emails=['charliea@chromium.org', 'nednguyen@chromium.org'])
 class MobileCommonSystemHealth(_CommonSystemHealthBenchmark):
   """Mobile Chrome Energy System Health Benchmark."""
   PLATFORM = 'mobile'
@@ -118,6 +120,7 @@
     return not _IGNORED_STATS_RE.search(value.name)
 
 
+@benchmark.Owner(emails=['perezju@chromium.org'])
 class DesktopMemorySystemHealth(_MemorySystemHealthBenchmark):
   """Desktop Chrome Memory System Health Benchmark."""
   PLATFORM = 'desktop'
@@ -132,6 +135,7 @@
 
 
 @benchmark.Enabled('android')
+@benchmark.Owner(emails=['perezju@chromium.org'])
 class MobileMemorySystemHealth(_MemorySystemHealthBenchmark):
   """Mobile Chrome Memory System Health Benchmark."""
   PLATFORM = 'mobile'
@@ -151,6 +155,7 @@
 
 
 @benchmark.Enabled('android-webview')
+@benchmark.Owner(emails=['perezju@chromium.org', 'torne@chromium.org'])
 class WebviewStartupSystemHealthBenchmark(perf_benchmark.PerfBenchmark):
   """Webview startup time benchmark
 
diff --git a/tools/perf/benchmarks/text_selection.py b/tools/perf/benchmarks/text_selection.py
index 17c7141..da2fbf5 100644
--- a/tools/perf/benchmarks/text_selection.py
+++ b/tools/perf/benchmarks/text_selection.py
@@ -38,6 +38,7 @@
 
 # See crbug.com/519044
 @benchmark.Disabled('all')
+@benchmark.Owner(emails=['mfomitchev@chromium.org'])
 class TextSelectionDirection(_TextSelection):
   """Measure text selection metrics while dragging a touch selection handle on a
   subset of top ten mobile sites and using the 'direction' touch selection
@@ -53,6 +54,7 @@
 
 # See crbug.com/519044
 @benchmark.Disabled('all')
+@benchmark.Owner(emails=['mfomitchev@chromium.org'])
 class TextSelectionCharacter(_TextSelection):
   """Measure text selection metrics while dragging a touch selection handle on a
   subset of top ten mobile sites and using the 'character' touch selection
diff --git a/tools/perf/benchmarks/thread_times.py b/tools/perf/benchmarks/thread_times.py
index bdbd50c..59ce362 100644
--- a/tools/perf/benchmarks/thread_times.py
+++ b/tools/perf/benchmarks/thread_times.py
@@ -34,6 +34,7 @@
 
 
 @benchmark.Enabled('android')
+@benchmark.Owner(emails=['vmiura@chromium.org'])
 class ThreadTimesKeySilkCases(_ThreadTimes):
   """Measures timeline metrics while performing smoothness action on key silk
   cases."""
@@ -69,6 +70,7 @@
 
 
 @benchmark.Enabled('android')
+@benchmark.Owner(emails=['vmiura@chromium.org'])
 class ThreadTimesSimpleMobileSites(_ThreadTimes):
   """Measures timeline metric using smoothness action on simple mobile sites
   http://www.chromium.org/developers/design-documents/rendering-benchmarks"""
@@ -79,6 +81,7 @@
     return 'thread_times.simple_mobile_sites'
 
 
+@benchmark.Owner(emails=['vmiura@chromium.org'])
 class ThreadTimesCompositorCases(_ThreadTimes):
   """Measures timeline metrics while performing smoothness action on
   tough compositor cases, using software rasterization.
@@ -96,6 +99,7 @@
 
 
 @benchmark.Enabled('android')
+@benchmark.Owner(emails=['ykyyip@chromium.org'])
 class ThreadTimesPolymer(_ThreadTimes):
   """Measures timeline metrics while performing smoothness action on
   Polymer cases."""
@@ -107,6 +111,7 @@
 
 
 @benchmark.Enabled('android')
+@benchmark.Owner(emails=['skyostil@chromium.org'])
 class ThreadTimesKeyIdlePowerCases(_ThreadTimes):
   """Measures timeline metrics for sites that should be idle in foreground
   and background scenarios. The metrics are per-second rather than per-frame."""
@@ -138,6 +143,7 @@
     return 'per_frame' not in value.name and 'mean_frame' not in value.name
 
 
+@benchmark.Owner(emails=['tdresser@chromium.org'])
 class ThreadTimesToughScrollingCases(_ThreadTimes):
   """Measure timeline metrics while performing smoothness action on tough
   scrolling cases."""
diff --git a/tools/perf/benchmarks/tracing.py b/tools/perf/benchmarks/tracing.py
index 71adb584..805ccdf 100644
--- a/tools/perf/benchmarks/tracing.py
+++ b/tools/perf/benchmarks/tracing.py
@@ -12,6 +12,9 @@
 import page_sets
 
 
+@benchmark.Owner(emails=['oysteine@chromium.org',
+                         'nednguyen@chromium.org',
+                         'zhenw@chromium.org'])
 class TracingWithDebugOverhead(perf_benchmark.PerfBenchmark):
 
   page_set = page_sets.Top10PageSet
@@ -30,6 +33,7 @@
 # TODO(ssid): Enable on reference builds once stable browser starts supporting
 # background mode memory-infra. crbug.com/621195.
 @benchmark.Disabled('reference')
+@benchmark.Owner(emails=['ssid@chromium.org'])
 class TracingWithBackgroundMemoryInfra(perf_benchmark.PerfBenchmark):
   """Measures the overhead of background memory-infra dumps"""
   page_set = page_sets.Top10PageSet
diff --git a/tools/perf/benchmarks/v8.py b/tools/perf/benchmarks/v8.py
index d0a04f5..80e2bf1 100644
--- a/tools/perf/benchmarks/v8.py
+++ b/tools/perf/benchmarks/v8.py
@@ -30,6 +30,7 @@
 
 
 @benchmark.Disabled('win')        # crbug.com/416502
+@benchmark.Owner(emails=['hpayer@chromium.org', 'rmcilroy@chromium.org'])
 class V8Top25(perf_benchmark.PerfBenchmark):
   """Measures V8 GC metrics on the while scrolling down the top 25 web pages.
 
@@ -48,6 +49,7 @@
 
 
 @benchmark.Enabled('android')
+@benchmark.Owner(emails=['hpayer@chromium.org', 'rmcilroy@chromium.org'])
 class V8KeyMobileSites(perf_benchmark.PerfBenchmark):
   """Measures V8 GC metrics on the while scrolling down key mobile sites.
 
@@ -123,6 +125,7 @@
     return True
 
 
+@benchmark.Owner(emails=['jochen@chromium.org'])
 class V8TodoMVC(perf_benchmark.PerfBenchmark):
   """Measures V8 Execution metrics on the TodoMVC examples."""
   page_set = page_sets.TodoMVCPageSet
@@ -145,6 +148,7 @@
     return True
 
 
+@benchmark.Owner(emails=['mvstaton@chromium.org'])
 class V8TodoMVCTurbo(V8TodoMVC):
   """Measures V8 Execution metrics on the TodoMVC examples
   using Ignition+TurboFan."""
@@ -161,6 +165,7 @@
 
 
 
+@benchmark.Owner(emails=['ulan@chromium.org'])
 class V8InfiniteScroll(_InfiniteScrollBenchmark):
   """Measures V8 GC metrics and memory usage while scrolling the top web pages.
   http://www.chromium.org/developers/design-documents/rendering-benchmarks"""
@@ -172,6 +177,7 @@
     return 'v8.infinite_scroll_tbmv2'
 
 
+@benchmark.Owner(emails=['mvstaton@chromium.org'])
 class V8InfiniteScrollTurbo(V8InfiniteScroll):
   """Measures V8 GC metrics using Ignition+TurboFan."""
 
@@ -185,6 +191,7 @@
 
 
 @benchmark.Enabled('android')
+@benchmark.Owner(emails=['ulan@chromium.org'])
 class V8MobileInfiniteScroll(_InfiniteScrollBenchmark):
   """Measures V8 GC metrics and memory usage while scrolling the top mobile
   web pages.
@@ -203,6 +210,7 @@
 
 
 @benchmark.Enabled('android')
+@benchmark.Owner(emails=['mvstaton@chromium.org'])
 class V8MobileInfiniteScrollTurbo(V8MobileInfiniteScroll):
   """Measures V8 GC metrics and memory usage while scrolling the top mobile
   web pages and running Ignition+TurboFan.
@@ -217,6 +225,7 @@
     return 'v8.mobile_infinite_scroll-turbo_tbmv2'
 
 
+@benchmark.Owner(emails=['hablich@chromium.org'])
 class V8Adword(perf_benchmark.PerfBenchmark):
   """Measures V8 Execution metrics on the Adword page."""
 
@@ -300,6 +309,7 @@
 
 
 @benchmark.Disabled('android', 'win', 'reference')  # crbug.com/664318
+@benchmark.Owner(emails=['cbruni@chromium.org'])
 class V8Top25RuntimeStats(_Top25RuntimeStats):
   """Runtime Stats benchmark for a 25 top V8 web pages.
 
diff --git a/tools/perf/benchmarks/v8_browsing.py b/tools/perf/benchmarks/v8_browsing.py
index 977f473..421c0fd 100644
--- a/tools/perf/benchmarks/v8_browsing.py
+++ b/tools/perf/benchmarks/v8_browsing.py
@@ -156,11 +156,13 @@
     return possible_browser.platform.GetDeviceTypeName() == 'Desktop'
 
 
+@benchmark.Owner(emails=['ulan@chromium.org'])
 class V8DesktopBrowsingBenchmark(_V8DesktopBrowsingBenchmark):
   PLATFORM = 'desktop'
   TEST_SUFFIX = ''
 
 
+@benchmark.Owner(emails=['ulan@chromium.org'])
 @benchmark.Disabled('reference')  # http://crbug.com/628631
 class V8MobileBrowsingBenchmark(_V8MobileBrowsingBenchmark):
   PLATFORM = 'mobile'
@@ -168,6 +170,7 @@
 
 
 @benchmark.Disabled('reference')  # http://crbug.com/700390
+@benchmark.Owner(emails=['mvstaton@chromium.org'])
 class V8DesktopTurboBrowsingBenchmark(_V8DesktopBrowsingBenchmark):
   PLATFORM = 'desktop'
   TEST_SUFFIX = '_turbo'
@@ -179,6 +182,7 @@
 
 
 @benchmark.Disabled('reference')  # http://crbug.com/628631
+@benchmark.Owner(emails=['mvstaton@chromium.org'])
 class V8MobileTurboBrowsingBenchmark(_V8MobileBrowsingBenchmark):
   PLATFORM = 'mobile'
   TEST_SUFFIX = '_turbo'
@@ -188,6 +192,7 @@
         options)
 
 
+@benchmark.Owner(emails=['mythria@chromium.org'])
 class V8RuntimeStatsDesktopBrowsingBenchmark(
     _V8RuntimeStatsBrowsingBenchmark):
   PLATFORM = 'desktop'
@@ -199,6 +204,7 @@
 
 
 @benchmark.Disabled('reference')  # http://crbug.com/700390
+@benchmark.Owner(emails=['mythria@chromium.org'])
 class V8RuntimeStatsDesktopTurboBrowsingBenchmark(
     _V8RuntimeStatsBrowsingBenchmark):
   PLATFORM = 'desktop'
@@ -215,6 +221,7 @@
 
 
 @benchmark.Disabled('reference')  # http://crbug.com/694658
+@benchmark.Owner(emails=['mythria@chromium.org'])
 class V8RuntimeStatsMobileBrowsingBenchmark(
     _V8RuntimeStatsBrowsingBenchmark):
   PLATFORM = 'mobile'
@@ -226,6 +233,7 @@
 
 
 @benchmark.Disabled('reference')  # http://crbug.com/694658
+@benchmark.Owner(emails=['mythria@chromium.org'])
 class V8RuntimeStatsMobileTurboBrowsingBenchmark(
     _V8RuntimeStatsBrowsingBenchmark):
   PLATFORM = 'mobile'
diff --git a/tools/perf/benchmarks/webrtc.py b/tools/perf/benchmarks/webrtc.py
index d9388a7..bf9582ab 100644
--- a/tools/perf/benchmarks/webrtc.py
+++ b/tools/perf/benchmarks/webrtc.py
@@ -41,6 +41,7 @@
     return 'webrtc.peerconnection'
 
 
+@benchmark.Owner(emails=['phoglund@chromium.org'])
 class WebrtcDataChannel(_Webrtc):
   """Measures WebRtc DataChannel loopback."""
   page_set = page_sets.WebrtcDatachannelPageSet
@@ -51,6 +52,7 @@
 
 
 @benchmark.Disabled('android')  # http://crbug.com/663802
+@benchmark.Owner(emails=['ehmaldonado@chromium.org', 'phoglund@chromium.org'])
 class WebrtcStressTest(perf_benchmark.PerfBenchmark):
   """Measures WebRtc CPU and GPU usage with multiple peer connections."""
   page_set = page_sets.WebrtcStresstestPageSet
@@ -71,6 +73,7 @@
 # capture. See http://crbug.com/603232.
 @benchmark.Disabled('reference')
 @benchmark.Disabled('android')  # http://crbug.com/610019
+@benchmark.Owner(emails=['qiangchen@chromium.org'])
 class WebrtcRendering(perf_benchmark.PerfBenchmark):
   """Specific time measurements (e.g. fps, smoothness) for WebRtc rendering."""
 
diff --git a/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java b/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java
index 368d9e78..2b10d1a5 100644
--- a/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java
+++ b/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java
@@ -54,6 +54,16 @@
     private static final String ALL_AUDIO_TYPES = AUDIO_TYPE + "*";
     private static final String ANY_TYPES = "*/*";
 
+    // A list of some of the more popular image extensions. Not meant to be
+    // exhaustive, but should cover the vast majority of image types.
+    private static final String[] POPULAR_IMAGE_EXTENSIONS = new String[] {".apng", ".bmp", ".gif",
+            ".jpeg", ".jpg", ".pdf", ".png", ".tif", ".tiff", ".xcf", ".webp"};
+
+    // A list of some of the more popular video extensions. Not meant to be
+    // exhaustive, but should cover the vast majority of video types.
+    private static final String[] POPULAR_VIDEO_EXTENSIONS = new String[] {".asf", ".avhcd", ".avi",
+            ".divx", ".flv", ".mov", ".mp4", ".mpeg", ".mpg", ".swf", ".wmv", ".webm", ".mkv"};
+
     /**
      * The SELECT_FILE_DIALOG_SCOPE_* enumerations are used to measure the sort of content that
      * developers are requesting to be shown in the select file dialog. Values must be kept in sync
@@ -388,8 +398,33 @@
     int determineSelectFileDialogScope() {
         if (mFileTypes.size() == 0) return SELECT_FILE_DIALOG_SCOPE_GENERIC;
 
+        // Capture the MIME types:
         int acceptsImages = countAcceptTypesFor(IMAGE_TYPE);
         int acceptsVideos = countAcceptTypesFor(VIDEO_TYPE);
+
+        // Capture the most common image and video extensions:
+        if (mFileTypes.size() > acceptsImages + acceptsVideos) {
+            for (String left : mFileTypes) {
+                boolean found = false;
+                for (String right : POPULAR_IMAGE_EXTENSIONS) {
+                    if (left.equalsIgnoreCase(right)) {
+                        found = true;
+                        acceptsImages++;
+                        break;
+                    }
+                }
+
+                if (found) continue;
+
+                for (String right : POPULAR_VIDEO_EXTENSIONS) {
+                    if (left.equalsIgnoreCase(right)) {
+                        acceptsVideos++;
+                        break;
+                    }
+                }
+            }
+        }
+
         int acceptsOthers = mFileTypes.size() - acceptsImages - acceptsVideos;
 
         if (acceptsOthers > 0) return SELECT_FILE_DIALOG_SCOPE_GENERIC;
diff --git a/ui/android/junit/src/org/chromium/ui/base/OWNERS b/ui/android/junit/src/org/chromium/ui/base/OWNERS
new file mode 100644
index 0000000..b9c1ca4
--- /dev/null
+++ b/ui/android/junit/src/org/chromium/ui/base/OWNERS
@@ -0,0 +1,5 @@
+# Implementation of the new in-app file picker.
+per-file SelectFileDialogTest.java=finnur@chromium.org
+per-file SelectFileDialogTest.java=peter@chromium.org
+
+# COMPONENT: UI
diff --git a/ui/android/junit/src/org/chromium/ui/base/SelectFileDialogTest.java b/ui/android/junit/src/org/chromium/ui/base/SelectFileDialogTest.java
index aaae9c83..91b45e2a 100644
--- a/ui/android/junit/src/org/chromium/ui/base/SelectFileDialogTest.java
+++ b/ui/android/junit/src/org/chromium/ui/base/SelectFileDialogTest.java
@@ -56,6 +56,30 @@
         assertEquals(SelectFileDialog.SELECT_FILE_DIALOG_SCOPE_GENERIC,
                 scopeForFileTypes("image/x-png", "image/gif", "image/jpeg", "text/plain"));
 
+        // Test image extensions only.
+        assertEquals(SelectFileDialog.SELECT_FILE_DIALOG_SCOPE_IMAGES,
+                scopeForFileTypes(".jpg", ".jpeg", ".png", ".gif", ".apng", ".tiff", ".tif", ".bmp",
+                        ".pdf", ".xcf", ".webp"));
+        // Test image extensions mixed with image MIME types.
+        assertEquals(SelectFileDialog.SELECT_FILE_DIALOG_SCOPE_IMAGES,
+                scopeForFileTypes(".JPG", ".jpeg", "image/gif", "image/jpeg"));
+        // Image extensions mixed with image MIME types and other.
+        assertEquals(SelectFileDialog.SELECT_FILE_DIALOG_SCOPE_GENERIC,
+                scopeForFileTypes(".jpg", "image/gif", "text/plain"));
+        // Video extensions only.
+        assertEquals(SelectFileDialog.SELECT_FILE_DIALOG_SCOPE_VIDEOS,
+                scopeForFileTypes(".asf", ".avhcd", ".avi", ".flv", ".mov", ".mp4", ".mpeg", ".mpg",
+                        ".swf", ".wmv", ".webm", ".mkv", ".divx"));
+        // Video extensions and video MIME types.
+        assertEquals(SelectFileDialog.SELECT_FILE_DIALOG_SCOPE_VIDEOS,
+                scopeForFileTypes(".avi", ".mp4", "video/ogg"));
+        // Video extensions and video MIME types and other.
+        assertEquals(SelectFileDialog.SELECT_FILE_DIALOG_SCOPE_GENERIC,
+                scopeForFileTypes(".avi", ".mp4", "video/ogg", "text/plain"));
+
+        // Non-image, non-video extension only.
+        assertEquals(SelectFileDialog.SELECT_FILE_DIALOG_SCOPE_GENERIC, scopeForFileTypes(".doc"));
+
         assertEquals(SelectFileDialog.SELECT_FILE_DIALOG_SCOPE_IMAGES_AND_VIDEOS,
                 scopeForFileTypes("video/*", "image/*"));
         assertEquals(SelectFileDialog.SELECT_FILE_DIALOG_SCOPE_IMAGES_AND_VIDEOS,