diff --git a/BUILD.gn b/BUILD.gn
index 044f7c6..edce1e2 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -205,8 +205,10 @@
   } else {
     deps += [
       "//ios/net:ios_net_unittests",
+      "//ios/public/provider/chrome/browser",
       "//ios/public/provider/web",
       "//ios/testing:ocmock_support_unittest",
+      "//ios/web/shell:ios_web_shell",
       "//ios/web:ios_web_unittests",
     ]
   }
@@ -389,7 +391,6 @@
       "//chrome/test:sync_performance_tests",
       "//chrome/test/chromedriver:chromedriver",
       "//chrome/test/chromedriver:chromedriver_tests",
-      "//chrome/tools/profile_reset:jtl_compiler",
       "//components:components_perftests",
       "//content/test:content_gl_tests",
       "//content/test:content_gl_benchmark",
diff --git a/DEPS b/DEPS
index 431a94c..b02f31e 100644
--- a/DEPS
+++ b/DEPS
@@ -39,11 +39,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': 'd6346290c2ef59abee453a72f3e91b4e7b62f4fa',
+  'skia_revision': '195fe08421f3a6c52ed621be96dbcc5393b41e69',
   # 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': '452eb33784734448cc9dca639dd6d44df49e4a4c',
+  'v8_revision': '9ac4a7402201283527c49026ce31e232b325227d',
   # 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.
@@ -187,10 +187,10 @@
    Var('chromium_git') + '/webm/libvpx.git' + '@' +  '0941ff72a00732cea6750477edfe649348e699de',
 
   'src/third_party/ffmpeg':
-   Var('chromium_git') + '/chromium/third_party/ffmpeg.git' + '@' + 'be6eebd8727037bd013e537e4783d2da6927293b',
+   Var('chromium_git') + '/chromium/third_party/ffmpeg.git' + '@' + '3540f6b0097b03aae1f29e41d8d8433044ee8cdb',
 
   'src/third_party/libjingle/source/talk':
-    Var('chromium_git') + '/external/webrtc/trunk/talk.git' + '@' + '146443f0b4ae5307b49b7500de975bc2e39cba4b', # commit position 10646
+    Var('chromium_git') + '/external/webrtc/trunk/talk.git' + '@' + '4cccfb61750309f0ec44170fcc098297f955f4db', # commit position 10659
 
   'src/third_party/usrsctp/usrsctplib':
     Var('chromium_git') + '/external/usrsctplib.git' + '@' + '36444a999739e9e408f8f587cb4c3ffeef2e50ac', # from svn revision 9215
@@ -214,7 +214,7 @@
    Var('chromium_git') + '/native_client/src/third_party/scons-2.0.1.git' + '@' + '1c1550e17fc26355d08627fbdec13d8291227067',
 
   'src/third_party/webrtc':
-    Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + '74bf4845fb2878f04756169abf1f1da5ae9971d5', # commit position 10649
+    Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + '1b5ad57a60538686c1c8ee2f2122642950182cca', # commit position 10669
 
   'src/third_party/openmax_dl':
     Var('chromium_git') + '/external/webrtc/deps/third_party/openmax.git' + '@' +  Var('openmax_dl_revision'),
diff --git a/WATCHLISTS b/WATCHLISTS
index 6c8a2f7..4f2e178c 100644
--- a/WATCHLISTS
+++ b/WATCHLISTS
@@ -1168,9 +1168,6 @@
       'filepath': 'third_party/WebKit/LayoutTests/imported/' \
                   '|third_party/WebKit/Tools/Scripts/webkitpy/w3c/'
     },
-    'blink_web_idl': {
-      'filepath': 'third_party/WebKit/Source/core/.*\.idl'
-    },
     'blink_webcomponents': {
       'filepath': 'third_party/WebKit/Source/core/dom/shadow/' \
                   '|third_party/WebKit/Source/core/dom/custom/' \
@@ -1554,7 +1551,6 @@
                             'mlamouri+watch-blink@chromium.org' ],
     'blink_device_orientation': [ 'timvolodine@chromium.org',
                                   'mvanouwerkerk+watch@chromium.org',
-                                  'ch.dumez@samsung.com',
                                   'mlamouri+watch-blink@chromium.org' ],
     'blink_devtools': [ 'pfeldman+blink@chromium.org',
                         'apavlov+blink@chromium.org',
@@ -1684,9 +1680,6 @@
     'blink_out_of_process_frames': [ 'dcheng@chromium.org',
                                      'mlamouri+watch-blink@chromium.org' ],
     'blink_screen_orientation': [ 'mlamouri+watch-blink@chromium.org' ],
-    'blink_web_idl': [ 'ch.dumez@samsung.com',
-                       'vivekg@chromium.org',
-                       'vivek.vg@samsung.com' ],
     'blink_websockets': [ 'tyoshino+watch@chromium.org',
                           'yhirano+watch@chromium.org' ],
     'blink_workers': [ 'blink-worker-reviews@chromium.org',
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContents.java b/android_webview/java/src/org/chromium/android_webview/AwContents.java
index bec617c..c610d5a 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContents.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java
@@ -930,8 +930,7 @@
         Activity activity = ContentViewCore.activityFromContext(context);
         if (activity == null) {
             if (sCachedWindowAndroid == null) {
-                sCachedWindowAndroid = new WindowAndroidWrapper(
-                        new WindowAndroid(context.getApplicationContext()));
+                sCachedWindowAndroid = new WindowAndroidWrapper(new WindowAndroid(context));
             }
             return sCachedWindowAndroid;
         }
diff --git a/ash/display/window_tree_host_manager.cc b/ash/display/window_tree_host_manager.cc
index af7d17c..aabf1b2 100644
--- a/ash/display/window_tree_host_manager.cc
+++ b/ash/display/window_tree_host_manager.cc
@@ -286,6 +286,8 @@
 }
 
 void WindowTreeHostManager::Shutdown() {
+  FOR_EACH_OBSERVER(Observer, observers_, OnWindowTreeHostManagerShutdown());
+
   // Unset the display manager's delegate here because
   // DisplayManager outlives WindowTreeHostManager.
   Shell::GetInstance()->display_manager()->set_delegate(nullptr);
diff --git a/ash/display/window_tree_host_manager.h b/ash/display/window_tree_host_manager.h
index 5d276992..67ae28d 100644
--- a/ash/display/window_tree_host_manager.h
+++ b/ash/display/window_tree_host_manager.h
@@ -72,7 +72,10 @@
 
     // Invoked when the all display configuration changes
     // have been applied.
-    virtual void OnDisplayConfigurationChanged(){};
+    virtual void OnDisplayConfigurationChanged() {}
+
+    // Invoked in WindowTreeHostManager::Shutdown().
+    virtual void OnWindowTreeHostManagerShutdown() {}
 
    protected:
     virtual ~Observer() {}
@@ -225,7 +228,7 @@
   // The mapping from display ID to its window tree host.
   WindowTreeHostMap window_tree_hosts_;
 
-  base::ObserverList<Observer> observers_;
+  base::ObserverList<Observer, true> observers_;
 
   // Store the primary window tree host temporarily while replacing
   // display.
diff --git a/ash/shell.cc b/ash/shell.cc
index 27697f67..b021e7b 100644
--- a/ash/shell.cc
+++ b/ash/shell.cc
@@ -1077,6 +1077,8 @@
   // is started.
   display_manager_->CreateMirrorWindowAsyncIfAny();
 
+  FOR_EACH_OBSERVER(ShellObserver, observers_, OnShellInitialized());
+
   user_metrics_recorder_->OnShellInitialized();
 }
 
diff --git a/ash/shell_observer.h b/ash/shell_observer.h
index 3ea105b..da53428 100644
--- a/ash/shell_observer.h
+++ b/ash/shell_observer.h
@@ -63,6 +63,9 @@
   // animating but have been restored.
   virtual void OnMaximizeModeEnded() {}
 
+  // Called at the end of Shell::Init.
+  virtual void OnShellInitialized() {}
+
  protected:
   virtual ~ShellObserver() {}
 };
diff --git a/breakpad/BUILD.gn b/breakpad/BUILD.gn
index 233c59715..08af6c7 100644
--- a/breakpad/BUILD.gn
+++ b/breakpad/BUILD.gn
@@ -725,6 +725,7 @@
 
 if (is_ios) {
   static_library("client") {
+    set_sources_assignment_filter([])
     sources = [
       "src/client/ios/Breakpad.h",
       "src/client/ios/Breakpad.mm",
@@ -751,6 +752,8 @@
       "src/client/minidump_file_writer.h",
       "src/common/convert_UTF.c",
       "src/common/convert_UTF.h",
+      "src/common/mac/GTMLogger.h",
+      "src/common/mac/GTMLogger.m",
       "src/common/mac/HTTPMultipartUpload.m",
       "src/common/mac/file_id.cc",
       "src/common/mac/file_id.h",
@@ -770,12 +773,20 @@
       "src/common/string_conversion.h",
       "src/google_breakpad/common/minidump_format.h",
     ]
+    set_sources_assignment_filter(sources_assignment_filter)
 
     include_dirs = [
       "src",
       "src/client/mac/Framework",
       "src/common/mac",
     ]
+
+    public_configs = [ ":client_config" ]
+
+    if (is_clang) {
+      # See https://bugs.chromium.org/p/google-breakpad/issues/detail?id=675.
+      cflags = [ "-Wno-deprecated-declarations" ]
+    }
   }
   # TODO(GYP) There is some XCode-only targets like ninja-breakpad.
 }
diff --git a/breakpad/breakpad.gyp b/breakpad/breakpad.gyp
index 52bf0db..5592748a 100644
--- a/breakpad/breakpad.gyp
+++ b/breakpad/breakpad.gyp
@@ -310,8 +310,7 @@
             ['OS=="ios"', {
               'xcode_settings' : {
                 'WARNING_CFLAGS': [
-                  # MinidumpGenerator uses an API deprecated in iOS 7.
-                  # crbug.com/408562
+                  # See https://bugs.chromium.org/p/google-breakpad/issues/detail?id=675.
                   '-Wno-deprecated-declarations',
                 ],
               },
diff --git a/build/all.gyp b/build/all.gyp
index ecbe935..176e855 100644
--- a/build/all.gyp
+++ b/build/all.gyp
@@ -109,7 +109,6 @@
           'dependencies': [
             '../third_party/re2/re2.gyp:re2',
             '../chrome/chrome.gyp:*',
-            '../chrome/tools/profile_reset/jtl_compiler.gyp:*',
             '../cc/blink/cc_blink_tests.gyp:*',
             '../cc/cc_tests.gyp:*',
             '../device/usb/usb.gyp:*',
diff --git a/build/gn_migration.gypi b/build/gn_migration.gypi
index 279d4c47..7c8b1a1 100644
--- a/build/gn_migration.gypi
+++ b/build/gn_migration.gypi
@@ -356,7 +356,6 @@
             '../chrome/chrome.gyp:performance_browser_tests',
             '../chrome/chrome.gyp:sync_integration_tests',
             '../chrome/chrome.gyp:sync_performance_tests',
-            '../chrome/tools/profile_reset/jtl_compiler.gyp:jtl_compiler',
             '../extensions/extensions_tests.gyp:extensions_browsertests',
             '../extensions/extensions_tests.gyp:extensions_unittests',
             '../gin/gin.gyp:gin_shell',
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/InvalidationGcmUpstreamSender.java b/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/InvalidationGcmUpstreamSender.java
index 2a1ff4f..1613dd07 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/InvalidationGcmUpstreamSender.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/InvalidationGcmUpstreamSender.java
@@ -42,7 +42,7 @@
         }
 
         // Attempt to retrieve a token for the user.
-        OAuth2TokenService.getOAuth2AccessToken(this, null, account,
+        OAuth2TokenService.getOAuth2AccessToken(this, account,
                 SyncConstants.CHROME_SYNC_OAUTH2_SCOPE,
                 new AccountManagerHelper.GetAuthTokenCallback() {
                     @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/AndroidProfileOAuth2TokenServiceHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/AndroidProfileOAuth2TokenServiceHelper.java
deleted file mode 100644
index 5a479887..0000000
--- a/chrome/android/java/src/org/chromium/chrome/browser/signin/AndroidProfileOAuth2TokenServiceHelper.java
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.signin;
-
-import android.accounts.Account;
-import android.app.Activity;
-import android.content.Context;
-
-import org.chromium.sync.signin.AccountManagerHelper;
-
-import java.util.concurrent.TimeUnit;
-
-import javax.annotation.Nullable;
-
-/**
- * Temporary wrapper class until all callers have moved to use {@link OAuth2TokenService}.
- * TODO(nyquist) Remove this class.
- */
-public final class AndroidProfileOAuth2TokenServiceHelper {
-
-    private AndroidProfileOAuth2TokenServiceHelper() {}
-
-    /**
-     * Use {@link OAuth2TokenService#getOAuth2AccessToken} instead.
-     */
-    @Deprecated
-    public static void getOAuth2AccessToken(Context context, @Nullable Activity activity,
-            Account account, String scope, AccountManagerHelper.GetAuthTokenCallback callback) {
-        OAuth2TokenService.getOAuth2AccessToken(context, activity, account, scope, callback);
-    }
-
-    /**
-     * Use {@link OAuth2TokenService#invalidateOAuth2AuthToken} instead.
-     */
-    @Deprecated
-    public static void invalidateOAuth2AuthToken(Context context, String accessToken) {
-        OAuth2TokenService.invalidateOAuth2AuthToken(context, accessToken);
-    }
-
-    /**
-     * Use {@link OAuth2TokenService#getOAuth2AccessTokenWithTimeout} instead.
-     */
-    @Deprecated
-    public static String getOAuth2AccessTokenWithTimeout(Context context,
-            @Nullable Activity activity, Account account, String scope,
-            long timeout, TimeUnit unit) {
-        return OAuth2TokenService.getOAuth2AccessTokenWithTimeout(
-                context, activity, account, scope, timeout, unit);
-    }
-}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/OAuth2TokenService.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/OAuth2TokenService.java
index 5103cdc..5cdc845 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/signin/OAuth2TokenService.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/OAuth2TokenService.java
@@ -5,7 +5,6 @@
 package org.chromium.chrome.browser.signin;
 
 import android.accounts.Account;
-import android.app.Activity;
 import android.content.Context;
 import android.preference.PreferenceManager;
 import android.util.Log;
@@ -25,8 +24,6 @@
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicReference;
 
-import javax.annotation.Nullable;
-
 /**
  * Java instance for the native OAuth2TokenService.
  * <p/>
@@ -165,13 +162,11 @@
     /**
      * Call this method to retrieve an OAuth2 access token for the given account and scope.
      *
-     * @param activity the current activity. May be null.
      * @param account the account to get the access token for.
      * @param scope The scope to get an auth token for (without Android-style 'oauth2:' prefix).
      * @param callback called on successful and unsuccessful fetching of auth token.
      */
-    public static void getOAuth2AccessToken(
-            Context context, @Nullable Activity activity, Account account, String scope,
+    public static void getOAuth2AccessToken(Context context, Account account, String scope,
             AccountManagerHelper.GetAuthTokenCallback callback) {
         String oauth2Scope = OAUTH2_SCOPE_PREFIX + scope;
         AccountManagerHelper.get(context).getAuthToken(account, oauth2Scope, callback);
@@ -183,7 +178,6 @@
      *
      * Given that this is a blocking method call, this should never be called from the UI thread.
      *
-     * @param activity the current activity. May be null.
      * @param account the account to get the access token for.
      * @param scope The scope to get an auth token for (without Android-style 'oauth2:' prefix).
      * @param timeout the timeout.
@@ -191,13 +185,12 @@
      */
     @VisibleForTesting
     public static String getOAuth2AccessTokenWithTimeout(
-            Context context, @Nullable Activity activity, Account account, String scope,
-            long timeout, TimeUnit unit) {
+            Context context, Account account, String scope, long timeout, TimeUnit unit) {
         assert !ThreadUtils.runningOnUiThread();
         final AtomicReference<String> result = new AtomicReference<String>();
         final Semaphore semaphore = new Semaphore(0);
         getOAuth2AccessToken(
-                context, activity, account, scope, new AccountManagerHelper.GetAuthTokenCallback() {
+                context, account, scope, new AccountManagerHelper.GetAuthTokenCallback() {
                     @Override
                     public void tokenAvailable(String token) {
                         result.set(token);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/OAuth2TokenServiceTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/OAuth2TokenServiceTest.java
index c08f7cf..432c62a 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/OAuth2TokenServiceTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/OAuth2TokenServiceTest.java
@@ -115,9 +115,8 @@
                         .authToken(oauth2Scope, expectedToken).build();
         mAccountManager.addAccountHolderExplicitly(accountHolder);
 
-        String accessToken =
-                OAuth2TokenService.getOAuth2AccessTokenWithTimeout(
-                        mContext, null, account, scope, 5, TimeUnit.SECONDS);
+        String accessToken = OAuth2TokenService.getOAuth2AccessTokenWithTimeout(
+                mContext, account, scope, 5, TimeUnit.SECONDS);
         assertEquals(expectedToken, accessToken);
     }
 }
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index f2916db..63ff3cae 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -8259,6 +8259,7 @@
           Unusual behavior detected
         </message>
       </if>
+
       <!-- Upgrade bubble messages -->
       <message name="IDS_REENABLE_UPDATES" desc="Text for the button the user clicks to re-enable automatic updates.">
         Enable autoupdate
@@ -10547,9 +10548,6 @@
         </message>
 
         <!-- Reset Profile Settings strings -->
-        <message name="IDS_RESET_PROFILE_SETTINGS_BANNER_TEXT" desc="The text to show in a banner at the top of the chrome://settings page. The banner is displayed when Chrome detects that the settings might have been changed without the user's knowledge.">
-          Some of your settings may have been changed without your knowledge.
-        </message>
         <message name="IDS_RESET_PROFILE_SETTINGS_SECTION_TITLE" desc="The title of the section in chrome://settings that allows resetting some settings in a profile">
           Reset settings
         </message>
diff --git a/chrome/browser/android/popular_sites.cc b/chrome/browser/android/popular_sites.cc
index c18c146..adb98a4 100644
--- a/chrome/browser/android/popular_sites.cc
+++ b/chrome/browser/android/popular_sites.cc
@@ -10,9 +10,11 @@
 #include "base/files/file_util.h"
 #include "base/json/json_reader.h"
 #include "base/path_service.h"
+#include "base/prefs/pref_service.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/task_runner_util.h"
+#include "base/time/time.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/net/file_downloader.h"
@@ -21,6 +23,7 @@
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "components/google/core/browser/google_util.h"
+#include "components/pref_registry/pref_registry_syncable.h"
 #include "components/search_engines/search_engine_type.h"
 #include "components/search_engines/template_url_prepopulate_data.h"
 #include "components/search_engines/template_url_service.h"
@@ -38,6 +41,8 @@
 const char kPopularSitesLocalFilename[] = "suggested_sites.json";
 const int kPopularSitesRedownloadIntervalHours = 24;
 
+const char kPopularSitesLastDownloadPref[] = "popular_sites_last_download";
+
 // Extract the country from the default search engine if the default search
 // engine is Google.
 std::string GetDefaultSearchEngineCountryCode(Profile* profile) {
@@ -203,62 +208,66 @@
 
 PopularSites::~PopularSites() {}
 
+// static
+void PopularSites::RegisterProfilePrefs(
+    user_prefs::PrefRegistrySyncable* user_prefs) {
+  user_prefs->RegisterInt64Pref(kPopularSitesLastDownloadPref, 0);
+}
+
 PopularSites::PopularSites(Profile* profile,
                            const GURL& url,
                            bool force_download,
                            const FinishedCallback& callback)
     : callback_(callback),
-      redownload_interval_(
-          base::TimeDelta::FromHours(kPopularSitesRedownloadIntervalHours)),
       popular_sites_local_path_(GetPopularSitesPath()),
+      profile_(profile),
       weak_ptr_factory_(this) {
   // Re-download the file once on every Chrome startup, but use the cached
   // local file afterwards.
   static bool first_time = true;
-  FetchPopularSites(url, profile, first_time || force_download);
+
+  const base::Time last_download_time = base::Time::FromInternalValue(
+      profile_->GetPrefs()->GetInt64(kPopularSitesLastDownloadPref));
+  const base::TimeDelta time_since_last_download =
+      base::Time::Now() - last_download_time;
+  const base::TimeDelta redownload_interval =
+      base::TimeDelta::FromHours(kPopularSitesRedownloadIntervalHours);
+  const bool download_time_is_future = base::Time::Now() < last_download_time;
+
+  const bool should_redownload_if_exists =
+      first_time || force_download || download_time_is_future ||
+      (time_since_last_download > redownload_interval);
+
+  FetchPopularSites(url, should_redownload_if_exists, false /* is_fallback */);
   first_time = false;
 }
 
 void PopularSites::FetchPopularSites(const GURL& url,
-                                     Profile* profile,
-                                     bool force_download) {
-  base::TimeDelta age = base::TimeTicks::Now() - last_download_time_;
-  bool redownload = force_download || (age > redownload_interval_);
+                                     bool force_download,
+                                     bool is_fallback) {
   downloader_.reset(
-      new FileDownloader(url, popular_sites_local_path_, redownload,
-                         profile->GetRequestContext(),
+      new FileDownloader(url, popular_sites_local_path_, force_download,
+                         profile_->GetRequestContext(),
                          base::Bind(&PopularSites::OnDownloadDone,
-                                    base::Unretained(this), profile)));
+                                    base::Unretained(this), is_fallback)));
 }
 
-void PopularSites::FetchFallbackSites(Profile* profile) {
-  downloader_.reset(new FileDownloader(
-      GetPopularSitesFallbackURL(profile), popular_sites_local_path_,
-      true /* force_download */, profile->GetRequestContext(),
-      base::Bind(&PopularSites::OnDownloadFallbackDone,
-                 base::Unretained(this))));
-}
-
-void PopularSites::OnDownloadDone(Profile* profile, bool success) {
+void PopularSites::OnDownloadDone(bool is_fallback, bool success) {
+  downloader_.reset();
   if (success) {
-    last_download_time_ = base::TimeTicks::Now();
+    profile_->GetPrefs()->SetInt64(kPopularSitesLastDownloadPref,
+                                   base::Time::Now().ToInternalValue());
     ParseSiteList(popular_sites_local_path_);
-    downloader_.reset();
-  } else {
+  } else if (!is_fallback) {
     DLOG(WARNING) << "Download country site list failed";
-    FetchFallbackSites(profile);
-  }
-}
-
-void PopularSites::OnDownloadFallbackDone(bool success) {
-  if (success) {
-    last_download_time_ = base::TimeTicks::Now();
-    ParseSiteList(popular_sites_local_path_);
+    // It is fine to force the download as Fallback is only triggered after a
+    // failed download.
+    FetchPopularSites(GetPopularSitesFallbackURL(profile_),
+                      true /* force_download */, true /* is_fallback */);
   } else {
     DLOG(WARNING) << "Download fallback site list failed";
     callback_.Run(false);
   }
-  downloader_.reset();
 }
 
 void PopularSites::ParseSiteList(const base::FilePath& path) {
diff --git a/chrome/browser/android/popular_sites.h b/chrome/browser/android/popular_sites.h
index af57a79..606a7c19 100644
--- a/chrome/browser/android/popular_sites.h
+++ b/chrome/browser/android/popular_sites.h
@@ -13,13 +13,16 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/strings/string16.h"
-#include "base/time/time.h"
 #include "url/gurl.h"
 
 namespace net {
 class URLRequestContextGetter;
 }
 
+namespace user_prefs {
+class PrefRegistrySyncable;
+}
+
 class FileDownloader;
 class Profile;
 
@@ -67,6 +70,10 @@
 
   const std::vector<Site>& sites() const { return sites_; }
 
+  // Register preferences used by this class.
+  static void RegisterProfilePrefs(
+      user_prefs::PrefRegistrySyncable* user_prefs);
+
  private:
   PopularSites(Profile* profile,
                const GURL& url,
@@ -76,14 +83,12 @@
   // Fetch the popular sites at the given URL. |force_download| should be true
   // if any previously downloaded site list should be overwritten.
   void FetchPopularSites(const GURL& url,
-                         Profile* profile,
-                         bool force_download);
-  void OnDownloadDone(Profile* profile, bool success);
+                         bool force_download,
+                         bool is_fallback);
 
-  // Fetch the default popular site list. This method will always overwrite
-  // a previously downloaded site list.
-  void FetchFallbackSites(Profile* profile);
-  void OnDownloadFallbackDone(bool success);
+  // If the download was not successful and it was not a fallback, attempt to
+  // download the fallback suggestions.
+  void OnDownloadDone(bool success, bool is_fallback);
 
   void ParseSiteList(const base::FilePath& path);
   void OnJsonParsed(scoped_ptr<std::vector<Site>> sites);
@@ -91,11 +96,11 @@
   FinishedCallback callback_;
   scoped_ptr<FileDownloader> downloader_;
   std::vector<Site> sites_;
-  base::TimeTicks last_download_time_;
 
-  base::TimeDelta redownload_interval_;
   base::FilePath popular_sites_local_path_;
 
+  Profile* profile_;
+
   base::WeakPtrFactory<PopularSites> weak_ptr_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(PopularSites);
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd
index 7e6595ac..04e83a76 100644
--- a/chrome/browser/browser_resources.grd
+++ b/chrome/browser/browser_resources.grd
@@ -403,10 +403,6 @@
       </if>
       <if expr="_google_chrome">
         <include name="IDR_PREF_HASH_SEED_BIN" file="resources\settings_internal\pref_hash_seed.bin" type="BINDATA" />
-        <include name="IDR_AUTOMATIC_PROFILE_RESET_RULES" file="internal\resources\profile_reset\automatic_profile_reset_rules.dat" type="BINDATA" />
-        <include name="IDR_AUTOMATIC_PROFILE_RESET_RULES_DRY" file="internal\resources\profile_reset\automatic_profile_reset_rules_dry.dat" type="BINDATA" />
-        <include name="IDR_AUTOMATIC_PROFILE_RESET_HASH_SEED" file="internal\resources\profile_reset\automatic_profile_reset_rules.seed" type="BINDATA" />
-        <include name="IDR_AUTOMATIC_PROFILE_RESET_HASH_SEED_DRY" file="internal\resources\profile_reset\automatic_profile_reset_rules_dry.seed" type="BINDATA" />
         <include name="IDR_ADDITIONAL_MODULE_IDS" file="${additional_modules_list_file}" use_base_dir="false" type="BINDATA" />
       </if>
       <if expr="chromeos">
diff --git a/chrome/browser/browsing_data/browsing_data_remover_unittest.cc b/chrome/browser/browsing_data/browsing_data_remover_unittest.cc
index 16feeab..d62aa5f 100644
--- a/chrome/browser/browsing_data/browsing_data_remover_unittest.cc
+++ b/chrome/browser/browsing_data/browsing_data_remover_unittest.cc
@@ -2124,7 +2124,7 @@
 TEST_F(BrowsingDataRemoverTest, RemovePasswordStatistics) {
   PasswordStoreFactory::GetInstance()->SetTestingFactoryAndUse(
       GetProfile(),
-      password_manager::BuildPasswordStoreService<
+      password_manager::BuildPasswordStore<
           content::BrowserContext, password_manager::MockPasswordStore>);
   password_manager::MockPasswordStore* store =
       static_cast<password_manager::MockPasswordStore*>(
diff --git a/chrome/browser/chromeos/login/saml/saml_browsertest.cc b/chrome/browser/chromeos/login/saml/saml_browsertest.cc
index 25f1e7d..fb3ca9ce 100644
--- a/chrome/browser/chromeos/login/saml/saml_browsertest.cc
+++ b/chrome/browser/chromeos/login/saml/saml_browsertest.cc
@@ -31,7 +31,9 @@
 #include "chrome/browser/chromeos/login/test/oobe_screen_waiter.h"
 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
 #include "chrome/browser/chromeos/login/ui/webui_login_display.h"
+#include "chrome/browser/chromeos/login/users/chrome_user_manager.h"
 #include "chrome/browser/chromeos/login/wizard_controller.h"
+#include "chrome/browser/chromeos/policy/affiliation_test_helper.h"
 #include "chrome/browser/chromeos/policy/device_policy_builder.h"
 #include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h"
 #include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h"
@@ -133,6 +135,8 @@
 const char kTestRefreshToken[] = "fake-refresh-token";
 const char kPolicy[] = "{\"managed_users\": [\"*\"]}";
 
+const char kAffiliationID[] = "some-affiliation-id";
+
 // FakeSamlIdp serves IdP auth form and the form submission. The form is
 // served with the template's RelayState placeholder expanded to the real
 // RelayState parameter from request. The form submission redirects back to
@@ -951,12 +955,10 @@
   SamlTest::SetUpInProcessBrowserTestFixture();
 
   // Initialize device policy.
-  test_helper_.InstallOwnerKey();
-  test_helper_.MarkAsEnterpriseOwned();
-  device_policy_->SetDefaultSigningKey();
-  device_policy_->Build();
-  fake_session_manager_client_->set_device_policy(device_policy_->GetBlob());
-  fake_session_manager_client_->OnPropertyChangeComplete(true);
+  std::set<std::string> device_affiliation_ids;
+  device_affiliation_ids.insert(kAffiliationID);
+  policy::affiliation_test_helper::SetDeviceAffiliationID(
+      &test_helper_, fake_session_manager_client_, device_affiliation_ids);
 
   // Initialize user policy.
   EXPECT_CALL(provider_, IsInitializationComplete(_))
@@ -978,6 +980,18 @@
       AccountId::FromUserEmail(kDifferentDomainSAMLUserEmail),
       user_manager::User::OAUTH2_TOKEN_STATUS_VALID);
 
+  // Give affiliated users appropriate affiliation IDs.
+  std::set<std::string> user_affiliation_ids;
+  user_affiliation_ids.insert(kAffiliationID);
+  chromeos::ChromeUserManager::Get()->SetUserAffiliation(kFirstSAMLUserEmail,
+                                                         user_affiliation_ids);
+  chromeos::ChromeUserManager::Get()->SetUserAffiliation(kSecondSAMLUserEmail,
+                                                         user_affiliation_ids);
+  chromeos::ChromeUserManager::Get()->SetUserAffiliation(kHTTPSAMLUserEmail,
+                                                         user_affiliation_ids);
+  chromeos::ChromeUserManager::Get()->SetUserAffiliation(kNonSAMLUserEmail,
+                                                         user_affiliation_ids);
+
   // Set up fake networks.
   DBusThreadManager::Get()
       ->GetShillManagerClient()
diff --git a/chrome/browser/chromeos/login/session/user_session_manager.cc b/chrome/browser/chromeos/login/session/user_session_manager.cc
index 7c2aa36..f06ccea 100644
--- a/chrome/browser/chromeos/login/session/user_session_manager.cc
+++ b/chrome/browser/chromeos/login/session/user_session_manager.cc
@@ -1017,14 +1017,14 @@
     // authentication cookies set by a SAML IdP on subsequent logins after the
     // first.
     bool transfer_saml_auth_cookies_on_subsequent_login = false;
-    if (has_auth_cookies_ &&
-        g_browser_process->platform_part()
-                ->browser_policy_connector_chromeos()
-                ->GetUserAffiliation(account_id.GetUserEmail()) ==
-            policy::USER_AFFILIATION_MANAGED) {
-      CrosSettings::Get()->GetBoolean(
-          kAccountsPrefTransferSAMLCookies,
-          &transfer_saml_auth_cookies_on_subsequent_login);
+    if (has_auth_cookies_) {
+      const user_manager::User* user =
+          user_manager::UserManager::Get()->FindUser(account_id);
+      if (user->is_affiliated()) {
+        CrosSettings::Get()->GetBoolean(
+            kAccountsPrefTransferSAMLCookies,
+            &transfer_saml_auth_cookies_on_subsequent_login);
+      }
     }
 
     // Transfers authentication-related data from the profile that was used for
diff --git a/chrome/browser/chromeos/platform_keys/platform_keys_nss.cc b/chrome/browser/chromeos/platform_keys/platform_keys_nss.cc
index 0bdb44b..2e81480c 100644
--- a/chrome/browser/chromeos/platform_keys/platform_keys_nss.cc
+++ b/chrome/browser/chromeos/platform_keys/platform_keys_nss.cc
@@ -25,7 +25,6 @@
 #include "chrome/browser/chromeos/certificate_provider/certificate_provider.h"
 #include "chrome/browser/chromeos/net/client_cert_filter_chromeos.h"
 #include "chrome/browser/chromeos/net/client_cert_store_chromeos.h"
-#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api.h"
 #include "chrome/browser/net/nss_context.h"
@@ -778,12 +777,9 @@
       chromeos::ProfileHelper::Get()->GetUserByProfile(
           Profile::FromBrowserContext(browser_context));
 
-  // Use the device-wide system key slot only if the user is of the same
-  // domain as the device is registered to.
-  policy::BrowserPolicyConnectorChromeOS* connector =
-      g_browser_process->platform_part()->browser_policy_connector_chromeos();
-  bool use_system_key_slot = connector->GetUserAffiliation(user->email()) ==
-                             policy::USER_AFFILIATION_MANAGED;
+  // Use the device-wide system key slot only if the user is affiliated on the
+  // device.
+  bool use_system_key_slot = user->is_affiliated();
 
   scoped_ptr<SelectCertificatesState> state(new SelectCertificatesState(
       user->username_hash(), use_system_key_slot, cert_request_info, callback));
diff --git a/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider_impl.cc b/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider_impl.cc
index 1c81969..672a6de 100644
--- a/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider_impl.cc
+++ b/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider_impl.cc
@@ -156,11 +156,9 @@
   }
   const user_manager::User* user =
       chromeos::ProfileHelper::Get()->GetUserByProfile(profile);
-  if (!user ||
-      g_browser_process->platform_part()->browser_policy_connector_chromeos()->
-          GetUserAffiliation(user->email()) != USER_AFFILIATION_MANAGED) {
-    // If the Profile belongs to a user who is not affiliated with the device's
-    // enrollment domain, ignore it.
+  if (!user || !user->is_affiliated()) {
+    // If the Profile belongs to a user who is not affiliated on the device,
+    // ignore it.
     return;
   }
 
diff --git a/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider_impl_unittest.cc b/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider_impl_unittest.cc
index 9009677..e0f9010 100644
--- a/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider_impl_unittest.cc
+++ b/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider_impl_unittest.cc
@@ -87,8 +87,10 @@
   void SetUp() override;
   void TearDown() override;
 
-  // Ownership is not passed. The Profile is owned by the global ProfileManager.
-  Profile* LogInAndReturnProfile(const std::string& user_id);
+  // Both functions don't pass ownership of the profile. The Profile is owned
+  // by the global ProfileManager.
+  Profile* LogInAndReturnAffiliatedProfile(const std::string& user_id);
+  Profile* LogInAndReturnNonAffiliatedProfile(const std::string& user_id);
 
   // Logs in as an affiliated user and indicates that the per-profile
   // invalidation service for this user connected. Verifies that this
@@ -116,6 +118,9 @@
       bool create);
 
  protected:
+  // Ownership is not passed. The Profile is owned by the global ProfileManager.
+  Profile* LogInAndReturnProfile(const std::string& user_id,
+                                 bool is_affiliated);
   scoped_ptr<AffiliatedInvalidationServiceProviderImpl> provider_;
   scoped_ptr<FakeConsumer> consumer_;
   invalidation::TiclInvalidationService* device_invalidation_service_;
@@ -220,9 +225,22 @@
   chromeos::SystemSaltGetter::Shutdown();
 }
 
-Profile* AffiliatedInvalidationServiceProviderImplTest::LogInAndReturnProfile(
+Profile*
+AffiliatedInvalidationServiceProviderImplTest::LogInAndReturnAffiliatedProfile(
     const std::string& user_id) {
-  fake_user_manager_->AddUser(AccountId::FromUserEmail(user_id));
+  return LogInAndReturnProfile(user_id, true);
+}
+
+Profile* AffiliatedInvalidationServiceProviderImplTest::
+    LogInAndReturnNonAffiliatedProfile(const std::string& user_id) {
+  return LogInAndReturnProfile(user_id, false);
+}
+
+Profile* AffiliatedInvalidationServiceProviderImplTest::LogInAndReturnProfile(
+    const std::string& user_id,
+    bool is_affiliated) {
+  fake_user_manager_->AddUserWithAffiliation(AccountId::FromUserEmail(user_id),
+                                             is_affiliated);
   Profile* profile = profile_manager_.CreateTestingProfile(user_id);
   content::NotificationService::current()->Notify(
       chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED,
@@ -234,7 +252,7 @@
 void AffiliatedInvalidationServiceProviderImplTest::
     LogInAsAffiliatedUserAndConnectInvalidationService() {
   // Log in as an affiliated user.
-  Profile* profile = LogInAndReturnProfile(kAffiliatedUserID1);
+  Profile* profile = LogInAndReturnAffiliatedProfile(kAffiliatedUserID1);
   EXPECT_TRUE(profile);
 
   // Verify that a per-profile invalidation service has been created.
@@ -260,7 +278,7 @@
 void AffiliatedInvalidationServiceProviderImplTest::
     LogInAsUnaffiliatedUserAndConnectInvalidationService() {
   // Log in as an unaffiliated user.
-  Profile* profile = LogInAndReturnProfile(kUnaffiliatedUserID);
+  Profile* profile = LogInAndReturnNonAffiliatedProfile(kUnaffiliatedUserID);
   EXPECT_TRUE(profile);
 
   // Verify that a per-profile invalidation service has been created.
@@ -335,7 +353,7 @@
   EXPECT_FALSE(provider_->GetDeviceInvalidationServiceForTest());
 
   // Log in as an affiliated user.
-  EXPECT_TRUE(LogInAndReturnProfile(kAffiliatedUserID1));
+  EXPECT_TRUE(LogInAndReturnAffiliatedProfile(kAffiliatedUserID1));
 
   // Verify that no device-global invalidation service has been created.
   EXPECT_FALSE(provider_->GetDeviceInvalidationServiceForTest());
@@ -506,7 +524,7 @@
   LogInAsAffiliatedUserAndConnectInvalidationService();
 
   // Log in as a second affiliated user.
-  Profile* second_profile = LogInAndReturnProfile(kAffiliatedUserID2);
+  Profile* second_profile = LogInAndReturnAffiliatedProfile(kAffiliatedUserID2);
   EXPECT_TRUE(second_profile);
 
   // Verify that the device-global invalidation service still does not exist.
@@ -605,7 +623,7 @@
   EXPECT_FALSE(provider_->GetDeviceInvalidationServiceForTest());
 
   // Log in as a second affiliated user.
-  Profile* second_profile = LogInAndReturnProfile(kAffiliatedUserID2);
+  Profile* second_profile = LogInAndReturnAffiliatedProfile(kAffiliatedUserID2);
   EXPECT_TRUE(second_profile);
 
   // Verify that the device-global invalidation service still does not exist.
diff --git a/chrome/browser/chromeos/policy/affiliation_test_helper.cc b/chrome/browser/chromeos/policy/affiliation_test_helper.cc
new file mode 100644
index 0000000..bfedc57d
--- /dev/null
+++ b/chrome/browser/chromeos/policy/affiliation_test_helper.cc
@@ -0,0 +1,138 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+#include "chrome/browser/chromeos/policy/affiliation_test_helper.h"
+
+#include <string>
+#include <vector>
+
+#include "base/command_line.h"
+#include "base/files/file_path.h"
+#include "base/path_service.h"
+#include "base/prefs/pref_service.h"
+#include "base/prefs/scoped_user_pref_update.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
+#include "chrome/browser/chromeos/login/existing_user_controller.h"
+#include "chrome/browser/chromeos/login/session/user_session_manager_test_api.h"
+#include "chrome/browser/chromeos/login/startup_utils.h"
+#include "chrome/browser/chromeos/policy/device_cloud_policy_store_chromeos.h"
+#include "chrome/browser/chromeos/policy/device_policy_builder.h"
+#include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h"
+#include "chromeos/chromeos_paths.h"
+#include "chromeos/chromeos_switches.h"
+#include "chromeos/dbus/cryptohome_client.h"
+#include "chromeos/dbus/fake_session_manager_client.h"
+#include "chromeos/dbus/session_manager_client.h"
+#include "chromeos/login/auth/key.h"
+#include "chromeos/login/auth/user_context.h"
+#include "components/policy/core/common/cloud/cloud_policy_core.h"
+#include "components/policy/core/common/cloud/cloud_policy_store.h"
+#include "components/policy/core/common/cloud/policy_builder.h"
+#include "content/public/browser/notification_service.h"
+#include "content/public/test/test_utils.h"
+#include "crypto/rsa_private_key.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace policy {
+
+namespace affiliation_test_helper {
+
+const char kFakeRefreshToken[] = "fake-refresh-token";
+const char kEnterpriseUser[] = "testuser@example.com";
+
+void SetUserKeys(policy::UserPolicyBuilder* user_policy) {
+  std::string username = user_policy->policy_data().username();
+  base::FilePath user_keys_dir;
+  ASSERT_TRUE(PathService::Get(chromeos::DIR_USER_POLICY_KEYS, &user_keys_dir));
+  const std::string sanitized_username =
+      chromeos::CryptohomeClient::GetStubSanitizedUsername(username);
+  const base::FilePath user_key_file =
+      user_keys_dir.AppendASCII(sanitized_username).AppendASCII("policy.pub");
+  std::vector<uint8> user_key_bits;
+  ASSERT_TRUE(user_policy->GetSigningKey()->ExportPublicKey(&user_key_bits));
+  ASSERT_TRUE(base::CreateDirectory(user_key_file.DirName()));
+  ASSERT_EQ(base::WriteFile(user_key_file,
+                            reinterpret_cast<const char*>(user_key_bits.data()),
+                            user_key_bits.size()),
+            static_cast<int>(user_key_bits.size()));
+}
+
+void SetDeviceAffiliationID(
+    policy::DevicePolicyCrosTestHelper* test_helper,
+    chromeos::FakeSessionManagerClient* fake_session_manager_client,
+    const std::set<std::string>& device_affiliation_ids) {
+  test_helper->InstallOwnerKey();
+  test_helper->MarkAsEnterpriseOwned();
+
+  policy::DevicePolicyBuilder* device_policy = test_helper->device_policy();
+  for (const auto& device_affiliation_id : device_affiliation_ids) {
+    device_policy->policy_data().add_device_affiliation_ids(
+        device_affiliation_id);
+  }
+  device_policy->SetDefaultSigningKey();
+  device_policy->Build();
+
+  fake_session_manager_client->set_device_policy(device_policy->GetBlob());
+  fake_session_manager_client->OnPropertyChangeComplete(true);
+}
+
+void SetUserAffiliationIDs(
+    policy::UserPolicyBuilder* user_policy,
+    chromeos::FakeSessionManagerClient* fake_session_manager_client,
+    const std::string& user_email,
+    const std::set<std::string>& user_affiliation_ids) {
+  user_policy->policy_data().set_username(user_email);
+  SetUserKeys(user_policy);
+  for (const auto& user_affiliation_id : user_affiliation_ids) {
+    user_policy->policy_data().add_user_affiliation_ids(user_affiliation_id);
+  }
+  user_policy->Build();
+  fake_session_manager_client->set_user_policy(user_email,
+                                               user_policy->GetBlob());
+}
+
+void PreLoginUser(const std::string& user_id) {
+  ListPrefUpdate users_pref(g_browser_process->local_state(), "LoggedInUsers");
+  users_pref->AppendIfNotPresent(new base::StringValue(user_id));
+  chromeos::StartupUtils::MarkOobeCompleted();
+}
+
+void LoginUser(const std::string& user_id) {
+  chromeos::test::UserSessionManagerTestApi session_manager_test_api(
+      chromeos::UserSessionManager::GetInstance());
+  session_manager_test_api.SetShouldObtainTokenHandleInTests(false);
+
+  chromeos::UserContext user_context(AccountId::FromUserEmail(user_id));
+  user_context.SetGaiaID("gaia-id-" + user_id);
+  user_context.SetKey(chromeos::Key("password"));
+  if (user_id == kEnterpriseUser) {
+    user_context.SetRefreshToken(kFakeRefreshToken);
+  }
+  chromeos::ExistingUserController* controller =
+      chromeos::ExistingUserController::current_controller();
+  CHECK(controller);
+  content::WindowedNotificationObserver observer(
+      chrome::NOTIFICATION_SESSION_STARTED,
+      content::NotificationService::AllSources());
+  controller->Login(user_context, chromeos::SigninSpecifics());
+  observer.Wait();
+
+  const user_manager::UserList& logged_users =
+      user_manager::UserManager::Get()->GetLoggedInUsers();
+  for (user_manager::UserList::const_iterator it = logged_users.begin();
+       it != logged_users.end(); ++it) {
+    if ((*it)->email() == user_context.GetAccountId().GetUserEmail())
+      return;
+  }
+  ADD_FAILURE() << user_id << " was not added via PreLoginUser()";
+}
+
+void AppendCommandLineSwitchesForLoginManager(base::CommandLine* command_line) {
+  command_line->AppendSwitch(chromeos::switches::kLoginManager);
+  command_line->AppendSwitch(chromeos::switches::kForceLoginManagerInTests);
+}
+
+}  // namespace affiliation_test_helper
+
+}  // namespace policy
diff --git a/chrome/browser/chromeos/policy/affiliation_test_helper.h b/chrome/browser/chromeos/policy/affiliation_test_helper.h
new file mode 100644
index 0000000..ee4624a2
--- /dev/null
+++ b/chrome/browser/chromeos/policy/affiliation_test_helper.h
@@ -0,0 +1,108 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_POLICY_AFFILIATION_TEST_HELPER_H_
+#define CHROME_BROWSER_CHROMEOS_POLICY_AFFILIATION_TEST_HELPER_H_
+
+#include <set>
+#include <string>
+#include "components/policy/core/common/cloud/policy_builder.h"
+
+namespace base {
+class CommandLine;
+}  // namespace base
+
+namespace chromeos {
+class FakeSessionManagerClient;
+}  // namespace chromeos
+
+namespace policy {
+
+class DevicePolicyCrosTestHelper;
+
+namespace affiliation_test_helper {
+
+// Creates policy key file for the user specified in |user_policy|.
+// TODO(peletskyi): Replace pointer with const reference and replace this
+// boilerplate in other places (http://crbug.com/549111).
+void SetUserKeys(policy::UserPolicyBuilder* user_policy);
+
+// Sets device affiliation ID to |fake_session_manager| from
+// |device_affiliation_ids| and modifies |test_helper| so that it contains
+// correct values of device affiliation IDs for future use. To add some device
+// policies and have device affiliation ID valid please use |test_helper|
+// modified by this function. Example:
+//
+// FakeSessionManagerClient* fake_session_manager_client =
+//   new chromeos::FakeSessionManagerClient;
+// DBusThreadManager::GetSetterForTesting()->SetSessionManagerClient(
+//   scoped_ptr<SessionManagerClient>(fake_session_manager_client));
+//
+// policy::DevicePolicyCrosTestHelper test_helper;
+// std::set<std::string> device_affiliation_ids;
+// device_affiliation_ids.insert(some-affiliation-id);
+//
+// affiliation_test_helper::SetDeviceAffiliationID(&test_helper,
+//                                                 fake_session_manager_client,
+//                                                 device_affiliation_ids);
+//
+// If it is used together with SetUserAffiliationIDs() (which is the most common
+// case) |fake_session_manager_client| must point to the same object as in
+// SetUserAffiliationIDs() call.
+// In browser tests one can call this function from
+// SetUpInProcessBrowserTestFixture().
+void SetDeviceAffiliationID(
+    policy::DevicePolicyCrosTestHelper* test_helper,
+    chromeos::FakeSessionManagerClient* fake_session_manager_client,
+    const std::set<std::string>& device_affiliation_ids);
+
+// Sets user affiliation ID for |user_name| to |fake_session_manager| from
+// |user_affiliation_ids| and modifies |user_policy| so that it contains
+// correct values of user affiliation IDs for future use. To add user policies
+// and have user affiliation IDs valid please use |user_policy| modified by this
+// function. Example:
+//
+// FakeSessionManagerClient* fake_session_manager_client =
+//    new chromeos::FakeSessionManagerClient;
+// DBusThreadManager::GetSetterForTesting()->SetSessionManagerClient(
+//    scoped_ptr<SessionManagerClient>(fake_session_manager_client));
+//
+// policy::UserPolicyBuilder user_policy;
+// std::set<std::string> user_affiliation_ids;
+// user_affiliation_ids.insert("some-affiliation-id");
+//
+// affiliation_test_helper::SetUserAffiliationIDs(
+//    &user_policy, fake_session_manager_client, "user@example.com",
+//    user_affiliation_ids);
+//
+// If it is used together SetDeviceAffiliationID() (which is the most common
+// case) |fake_session_manager_client| must point to the same object as in
+// SetDeviceAffiliationID() call.
+// In browser tests one can call this function from
+// SetUpInProcessBrowserTestFixture().
+void SetUserAffiliationIDs(
+    policy::UserPolicyBuilder* user_policy,
+    chromeos::FakeSessionManagerClient* fake_session_manager_client,
+    const std::string& user_email,
+    const std::set<std::string>& user_affiliation_ids);
+
+// Registers the user with the given |user_id| on the device and marks OOBE
+// as completed. This method should be called in PRE_* test.
+void PreLoginUser(const std::string& user_id);
+
+// Log in user with |user_id|. User should be registered using PreLoginUser().
+void LoginUser(const std::string& user_id);
+
+// Set necessary for login command line switches. Execute it in
+// SetUpCommandLine().
+void AppendCommandLineSwitchesForLoginManager(base::CommandLine* command_line);
+
+extern const char kFakeRefreshToken[];
+extern const char kEnterpriseUser[];
+
+}  // namespace affiliation_test_helper
+
+}  // namespace policy
+
+#endif  // CHROME_BROWSER_CHROMEOS_POLICY_AFFILIATION_TEST_HELPER_H_
diff --git a/chrome/browser/chromeos/policy/blocking_login_browsertest.cc b/chrome/browser/chromeos/policy/blocking_login_browsertest.cc
index f3ce1e1..47f0a65 100644
--- a/chrome/browser/chromeos/policy/blocking_login_browsertest.cc
+++ b/chrome/browser/chromeos/policy/blocking_login_browsertest.cc
@@ -243,8 +243,6 @@
     EXPECT_TRUE(browser_policy_connector()->IsEnterpriseManaged());
     EXPECT_EQ(kDomain, browser_policy_connector()->GetEnterpriseDomain());
     EXPECT_FALSE(profile_added_);
-    EXPECT_EQ(policy::USER_AFFILIATION_MANAGED,
-              browser_policy_connector()->GetUserAffiliation(kUsername));
     RunUntilIdle();
     EXPECT_FALSE(
         user_manager->IsKnownUser(AccountId::FromUserEmail(kUsername)));
diff --git a/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc b/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc
index 7005f7f2..8ed5b15 100644
--- a/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc
+++ b/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc
@@ -284,25 +284,6 @@
   return EnrollmentConfig();
 }
 
-UserAffiliation BrowserPolicyConnectorChromeOS::GetUserAffiliation(
-    const std::string& user_name) {
-  // An empty username means incognito user in case of ChromiumOS and
-  // no logged-in user in case of Chromium (SigninService). Many tests use
-  // nonsense email addresses (e.g. 'test') so treat those as non-enterprise
-  // users.
-  if (user_name.empty() || user_name.find('@') == std::string::npos)
-    return USER_AFFILIATION_NONE;
-
-  if (install_attributes_ &&
-      (gaia::ExtractDomainName(gaia::CanonicalizeEmail(user_name)) ==
-           install_attributes_->GetDomain() ||
-       policy::IsDeviceLocalAccountUser(user_name, NULL))) {
-    return USER_AFFILIATION_MANAGED;
-  }
-
-  return USER_AFFILIATION_NONE;
-}
-
 void BrowserPolicyConnectorChromeOS::SetUserPolicyDelegate(
     ConfigurationPolicyProvider* user_policy_provider) {
   global_user_cloud_policy_provider_->SetDelegate(user_policy_provider);
diff --git a/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h b/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h
index 6242695..41164c2 100644
--- a/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h
+++ b/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h
@@ -84,10 +84,6 @@
   // for details.
   EnrollmentConfig GetPrescribedEnrollmentConfig() const;
 
-  // Works out the user affiliation by checking the given |user_name| against
-  // the installation attributes.
-  UserAffiliation GetUserAffiliation(const std::string& user_name);
-
   DeviceCloudPolicyManagerChromeOS* GetDeviceCloudPolicyManager() {
     return device_cloud_policy_manager_;
   }
diff --git a/chrome/browser/chromeos/policy/device_local_account_browsertest.cc b/chrome/browser/chromeos/policy/device_local_account_browsertest.cc
index f7f4019..7358ab0 100644
--- a/chrome/browser/chromeos/policy/device_local_account_browsertest.cc
+++ b/chrome/browser/chromeos/policy/device_local_account_browsertest.cc
@@ -121,10 +121,12 @@
 #include "extensions/browser/app_window/app_window.h"
 #include "extensions/browser/app_window/app_window_registry.h"
 #include "extensions/browser/app_window/native_app_window.h"
+#include "extensions/browser/extension_registry.h"
 #include "extensions/browser/extension_system.h"
 #include "extensions/browser/install/crx_install_error.h"
 #include "extensions/browser/management_policy.h"
 #include "extensions/browser/notification_types.h"
+#include "extensions/browser/test_extension_registry_observer.h"
 #include "extensions/common/constants.h"
 #include "extensions/common/extension.h"
 #include "net/base/url_util.h"
@@ -373,13 +375,6 @@
   }
 }
 
-bool DoesInstallSuccessReferToId(const std::string& id,
-                                 const content::NotificationSource& source,
-                                 const content::NotificationDetails& details) {
-  return content::Details<const extensions::InstalledExtensionInfo>(details)->
-      extension->id() == id;
-}
-
 bool DoesInstallFailureReferToId(const std::string& id,
                                  const content::NotificationSource& source,
                                  const content::NotificationDetails& details) {
@@ -811,6 +806,71 @@
   return user_manager::UserManager::Get()->IsKnownUser(account_id);
 }
 
+// Helper that listen extension installation when new profile is created.
+class ExtensionInstallObserver : public content::NotificationObserver,
+                                 public extensions::ExtensionRegistryObserver {
+ public:
+  explicit ExtensionInstallObserver(const std::string& extension_id)
+      : registry_(nullptr),
+        waiting_extension_id_(extension_id),
+        observed_(false) {
+    registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CREATED,
+                   content::NotificationService::AllSources());
+  }
+
+  ~ExtensionInstallObserver() override {
+    if (registry_ != nullptr)
+      registry_->RemoveObserver(this);
+  }
+
+  // Wait until an extension with |extension_id| is installed.
+  void Wait() {
+    if (!observed_)
+      run_loop_.Run();
+  }
+
+ private:
+  // extensions::ExtensionRegistryObserver:
+  void OnExtensionWillBeInstalled(content::BrowserContext* browser_context,
+                                  const extensions::Extension* extension,
+                                  bool is_update,
+                                  bool from_ephemeral,
+                                  const std::string& old_name) override {
+    if (waiting_extension_id_ == extension->id()) {
+      observed_ = true;
+      run_loop_.Quit();
+    }
+  }
+
+  // content::NotificationObserver:
+  void Observe(int type,
+               const content::NotificationSource& source,
+               const content::NotificationDetails& details) override {
+    DCHECK_EQ(chrome::NOTIFICATION_PROFILE_CREATED, type);
+
+    Profile* profile = content::Source<Profile>(source).ptr();
+    registry_ = extensions::ExtensionRegistry::Get(profile);
+
+    // Check if extension is already installed with newly created profile.
+    if (registry_->GetInstalledExtension(waiting_extension_id_)) {
+      observed_ = true;
+      run_loop_.Quit();
+      return;
+    }
+
+    // Start listening for extension installation.
+    registry_->AddObserver(this);
+  }
+
+  extensions::ExtensionRegistry* registry_;
+  base::RunLoop run_loop_;
+  content::NotificationRegistrar registrar_;
+  std::string waiting_extension_id_;
+  bool observed_;
+
+  DISALLOW_COPY_AND_ASSIGN(ExtensionInstallObserver);
+};
+
 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, LoginScreen) {
   AddPublicSessionToDevicePolicy(kAccountId1);
   AddPublicSessionToDevicePolicy(kAccountId2);
@@ -1046,19 +1106,16 @@
   WaitForPolicy();
 
   // Start listening for app/extension installation results.
-  content::WindowedNotificationObserver hosted_app_observer(
-      extensions::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED,
-      base::Bind(DoesInstallSuccessReferToId, kHostedAppID));
+  ExtensionInstallObserver install_observer(kHostedAppID);
   content::WindowedNotificationObserver extension_observer(
       extensions::NOTIFICATION_EXTENSION_INSTALL_ERROR,
       base::Bind(DoesInstallFailureReferToId, kGoodExtensionID));
-
   ASSERT_NO_FATAL_FAILURE(StartLogin(std::string(), std::string()));
 
   // Wait for the hosted app installation to succeed and the extension
   // installation to fail (because hosted apps are whitelisted for use in
   // device-local accounts and extensions are not).
-  hosted_app_observer.Wait();
+  install_observer.Wait();
   extension_observer.Wait();
 
   // Verify that the hosted app was installed.
@@ -1127,9 +1184,7 @@
   WaitForPolicy();
 
   // Start listening for app/extension installation results.
-  content::WindowedNotificationObserver hosted_app_observer(
-      extensions::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED,
-      base::Bind(DoesInstallSuccessReferToId, kHostedAppID));
+  ExtensionInstallObserver install_observer(kHostedAppID);
   content::WindowedNotificationObserver extension_observer(
       extensions::NOTIFICATION_EXTENSION_INSTALL_ERROR,
       base::Bind(DoesInstallFailureReferToId, kGoodExtensionID));
@@ -1138,7 +1193,7 @@
 
   // Wait for the hosted app installation to succeed and the extension
   // installation to fail.
-  hosted_app_observer.Wait();
+  install_observer.Wait();
   extension_observer.Wait();
 
   // Verify that the hosted app was installed.
@@ -1258,9 +1313,7 @@
   WaitForPolicy();
 
   // Start listening for app/extension installation results.
-  content::WindowedNotificationObserver hosted_app_observer(
-      extensions::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED,
-      base::Bind(DoesInstallSuccessReferToId, kHostedAppID));
+  ExtensionInstallObserver install_observer(kHostedAppID);
   content::WindowedNotificationObserver extension_observer(
       extensions::NOTIFICATION_EXTENSION_INSTALL_ERROR,
       base::Bind(DoesInstallFailureReferToId, kGoodExtensionID));
@@ -1270,7 +1323,7 @@
   // Wait for the hosted app installation to succeed and the extension
   // installation to fail (because hosted apps are whitelisted for use in
   // device-local accounts and extensions are not).
-  hosted_app_observer.Wait();
+  install_observer.Wait();
   extension_observer.Wait();
 
   // Verify that the extension was kept in the local cache.
@@ -2199,12 +2252,10 @@
   WaitForPolicy();
 
   // Observe the app installation after login.
-  content::WindowedNotificationObserver extension_observer(
-      extensions::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED,
-      base::Bind(DoesInstallSuccessReferToId, kShowManagedStorageID));
+  ExtensionInstallObserver install_observer(kShowManagedStorageID);
   ASSERT_NO_FATAL_FAILURE(StartLogin(std::string(), std::string()));
   WaitForSessionStart();
-  extension_observer.Wait();
+  install_observer.Wait();
 
   // Verify that the app was installed.
   Profile* profile = GetProfileForTest();
diff --git a/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc b/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc
index 3b15701..03ea6c0 100644
--- a/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc
+++ b/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc
@@ -809,6 +809,18 @@
         new base::StringValue(container.login_screen_domain_auto_complete()),
         nullptr);
   }
+
+  if (policy.has_display_rotation_default()) {
+    const em::DisplayRotationDefaultProto& container(
+        policy.display_rotation_default());
+    policies->Set(
+        key::kDisplayRotationDefault,
+        POLICY_LEVEL_MANDATORY,
+        POLICY_SCOPE_MACHINE,
+        POLICY_SOURCE_CLOUD,
+        DecodeIntegerValue(container.display_rotation_default()).release(),
+        nullptr);
+  }
 }
 
 }  // namespace
diff --git a/chrome/browser/chromeos/policy/display_rotation_default_handler.cc b/chrome/browser/chromeos/policy/display_rotation_default_handler.cc
new file mode 100644
index 0000000..03f72fb
--- /dev/null
+++ b/chrome/browser/chromeos/policy/display_rotation_default_handler.cc
@@ -0,0 +1,109 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/policy/display_rotation_default_handler.h"
+
+#include <stddef.h>
+
+#include "ash/display/display_manager.h"
+#include "ash/shell.h"
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/location.h"
+#include "base/logging.h"
+#include "base/memory/ref_counted.h"
+#include "base/single_thread_task_runner.h"
+#include "base/thread_task_runner_handle.h"
+#include "chromeos/settings/cros_settings_names.h"
+
+namespace policy {
+
+DisplayRotationDefaultHandler::DisplayRotationDefaultHandler() {
+  ash::Shell::GetInstance()->window_tree_host_manager()->AddObserver(this);
+  ash::Shell::GetInstance()->AddShellObserver(this);
+  settings_observer_ = chromeos::CrosSettings::Get()->AddSettingsObserver(
+      chromeos::kDisplayRotationDefault,
+      base::Bind(&DisplayRotationDefaultHandler::OnCrosSettingsChanged,
+                 base::Unretained(this)));
+}
+
+DisplayRotationDefaultHandler::~DisplayRotationDefaultHandler() {
+}
+
+void DisplayRotationDefaultHandler::OnShellInitialized() {
+  UpdateFromCrosSettings();
+  RotateDisplays();
+}
+
+void DisplayRotationDefaultHandler::OnDisplayConfigurationChanged() {
+  RotateDisplays();
+}
+
+void DisplayRotationDefaultHandler::OnWindowTreeHostManagerShutdown() {
+  ash::Shell::GetInstance()->window_tree_host_manager()->RemoveObserver(this);
+  ash::Shell::GetInstance()->RemoveShellObserver(this);
+  settings_observer_.reset();
+  base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
+}
+
+void DisplayRotationDefaultHandler::OnCrosSettingsChanged() {
+  if (!UpdateFromCrosSettings())
+    return;
+  // Policy changed, so reset all displays.
+  rotated_displays_.clear();
+  RotateDisplays();
+}
+
+void DisplayRotationDefaultHandler::RotateDisplays() {
+  if (!policy_enabled_ || rotation_in_progress_)
+    return;
+
+  // Avoid nested calls of this function due to OnDisplayConfigurationChanged
+  // being called by rotations here.
+  rotation_in_progress_ = true;
+
+  ash::DisplayManager* const display_manager =
+      ash::Shell::GetInstance()->display_manager();
+  const size_t num_displays = display_manager->GetNumDisplays();
+  for (size_t i = 0; i < num_displays; ++i) {
+    const gfx::Display& display = display_manager->GetDisplayAt(i);
+    const int64_t id = display.id();
+    if (rotated_displays_.find(id) == rotated_displays_.end()) {
+      rotated_displays_.insert(id);
+      if (display.rotation() != display_rotation_default_) {
+        display_manager->SetDisplayRotation(id, display_rotation_default_,
+            gfx::Display::ROTATION_SOURCE_ACTIVE);
+      }
+    }
+  }
+  rotation_in_progress_ = false;
+}
+
+bool DisplayRotationDefaultHandler::UpdateFromCrosSettings() {
+  int new_rotation;
+  bool new_policy_enabled = chromeos::CrosSettings::Get()->GetInteger(
+      chromeos::kDisplayRotationDefault, &new_rotation);
+  gfx::Display::Rotation new_display_rotation_default = gfx::Display::ROTATE_0;
+  if (new_policy_enabled) {
+    if (new_rotation >= gfx::Display::ROTATE_0 &&
+        new_rotation <= gfx::Display::ROTATE_270) {
+      new_display_rotation_default =
+          static_cast<gfx::Display::Rotation>(new_rotation);
+    } else {
+      LOG(ERROR) << "CrosSettings contains invalid value " << new_rotation
+                 << " for DisplayRotationDefault. Ignoring setting.";
+      new_policy_enabled = false;
+    }
+  }
+  if (new_policy_enabled != policy_enabled_ ||
+      (new_policy_enabled &&
+       new_display_rotation_default != display_rotation_default_)) {
+    policy_enabled_ = new_policy_enabled;
+    display_rotation_default_ = new_display_rotation_default;
+    return true;
+  }
+  return false;
+}
+
+}  // namespace policy
diff --git a/chrome/browser/chromeos/policy/display_rotation_default_handler.h b/chrome/browser/chromeos/policy/display_rotation_default_handler.h
new file mode 100644
index 0000000..8c9bcd0
--- /dev/null
+++ b/chrome/browser/chromeos/policy/display_rotation_default_handler.h
@@ -0,0 +1,70 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_POLICY_DISPLAY_ROTATION_DEFAULT_HANDLER_H_
+#define CHROME_BROWSER_CHROMEOS_POLICY_DISPLAY_ROTATION_DEFAULT_HANDLER_H_
+
+#include <stdint.h>
+
+#include <set>
+
+#include "ash/display/window_tree_host_manager.h"
+#include "ash/shell_observer.h"
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "chrome/browser/chromeos/settings/cros_settings.h"
+#include "ui/gfx/display.h"
+
+namespace policy {
+
+// Enforces the device policy DisplayRotationDefault.
+// This class is created in ChromeShellDelegate::PreInit() and registers
+// itself with WindowTreeHostManager as Observer for display changes, and
+// with CrosSettings as Observer for setting changes. Whenever there is a change
+// in the display configuration, any new display with an id that is not already
+// in rotated_displays_ will be rotated according to the policy. When there is a
+// change to the CrosSettings, the new policy is applied to all connected
+// displays.
+// This class owns itself and destroys itself when OnShutdown is called by
+// WindowTreeHostManager.
+class DisplayRotationDefaultHandler
+    : public ash::WindowTreeHostManager::Observer,
+      public ash::ShellObserver {
+ public:
+  DisplayRotationDefaultHandler();
+  ~DisplayRotationDefaultHandler() override;
+
+  // ash::ShellObserver:
+  void OnShellInitialized() override;
+
+  // ash::WindowTreeHostManager::Observer:
+  void OnDisplayConfigurationChanged() override;
+  void OnWindowTreeHostManagerShutdown() override;
+
+ private:
+  // Callback function for settings_observer_.
+  void OnCrosSettingsChanged();
+
+  // Applies the policy to all connected displays as necessary.
+  void RotateDisplays();
+
+  // Reads |chromeos::kDisplayRotationDefault| from CrosSettings and stores
+  // its value, and whether it has a value, in member variables
+  // |display_rotation_default_| and |policy_enabled_|. Returns true if the
+  // setting changed.
+  bool UpdateFromCrosSettings();
+
+  bool policy_enabled_ = false;
+  gfx::Display::Rotation display_rotation_default_ = gfx::Display::ROTATE_0;
+  std::set<int64_t> rotated_displays_;
+  bool rotation_in_progress_ = false;
+
+  scoped_ptr<chromeos::CrosSettings::ObserverSubscription> settings_observer_;
+
+  DISALLOW_COPY_AND_ASSIGN(DisplayRotationDefaultHandler);
+};
+
+}  // namespace policy
+
+#endif  // CHROME_BROWSER_CHROMEOS_POLICY_DISPLAY_ROTATION_DEFAULT_HANDLER_H_
diff --git a/chrome/browser/chromeos/policy/display_rotation_default_handler_browsertest.cc b/chrome/browser/chromeos/policy/display_rotation_default_handler_browsertest.cc
new file mode 100644
index 0000000..1686ff3
--- /dev/null
+++ b/chrome/browser/chromeos/policy/display_rotation_default_handler_browsertest.cc
@@ -0,0 +1,234 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/policy/display_rotation_default_handler.h"
+
+#include "ash/display/display_manager.h"
+#include "ash/shell.h"
+#include "base/bind.h"
+#include "base/command_line.h"
+#include "base/location.h"
+#include "base/message_loop/message_loop.h"
+#include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
+#include "chrome/browser/chromeos/policy/device_policy_builder.h"
+#include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h"
+#include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h"
+#include "chrome/browser/lifetime/application_lifetime.h"
+#include "chromeos/chromeos_switches.h"
+#include "chromeos/settings/cros_settings_names.h"
+#include "content/public/test/test_utils.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace em = enterprise_management;
+
+namespace policy {
+
+class DisplayRotationDefaultTest
+    : public policy::DevicePolicyCrosBrowserTest,
+      public testing::WithParamInterface<gfx::Display::Rotation> {
+ public:
+  DisplayRotationDefaultTest() {}
+
+  void SetUpCommandLine(base::CommandLine* command_line) override {
+    command_line->AppendSwitch(chromeos::switches::kLoginManager);
+    command_line->AppendSwitch(chromeos::switches::kForceLoginManagerInTests);
+  }
+
+  void SetUpInProcessBrowserTestFixture() override {
+    InstallOwnerKey();
+    MarkAsEnterpriseOwned();
+    DevicePolicyCrosBrowserTest::SetUpInProcessBrowserTestFixture();
+  }
+
+  void TearDownOnMainThread() override {
+    // If the login display is still showing, exit gracefully.
+    if (chromeos::LoginDisplayHostImpl::default_host()) {
+      base::MessageLoop::current()->PostTask(FROM_HERE,
+                                             base::Bind(&chrome::AttemptExit));
+      content::RunMessageLoop();
+    }
+  }
+
+ protected:
+  void SetPolicy(int rotation) {
+    em::ChromeDeviceSettingsProto& proto(device_policy()->payload());
+    proto.mutable_display_rotation_default()->set_display_rotation_default(
+        static_cast<em::DisplayRotationDefaultProto::Rotation>(rotation));
+    RefreshPolicyAndWaitUntilDeviceSettingsUpdated();
+  }
+
+  // This is needed to test that refreshing the settings without change to the
+  // DisplayRotationDefault policy will not rotate the display again.
+  void SetADifferentPolicy() {
+    em::ChromeDeviceSettingsProto& proto(device_policy()->payload());
+    const bool clock24 = proto.use_24hour_clock().use_24hour_clock();
+    proto.mutable_use_24hour_clock()->set_use_24hour_clock(!clock24);
+    RefreshPolicyAndWaitUntilDeviceSettingsUpdated();
+  }
+
+  void UnsetPolicy() {
+    em::ChromeDeviceSettingsProto& proto(device_policy()->payload());
+    proto.clear_display_rotation_default();
+    RefreshPolicyAndWaitUntilDeviceSettingsUpdated();
+  }
+
+  ash::DisplayManager* GetDisplayManager() const {
+    return ash::Shell::GetInstance()->display_manager();
+  }
+
+  gfx::Display::Rotation GetRotationOfFirstDisplay() const {
+    const ash::DisplayManager* const display_manager = GetDisplayManager();
+    const int64_t first_display_id = display_manager->first_display_id();
+    const gfx::Display& first_display =
+        display_manager->GetDisplayForId(first_display_id);
+    return first_display.rotation();
+  }
+
+  // Fails the test and returns ROTATE_0 if there is no second display.
+  gfx::Display::Rotation GetRotationOfSecondDisplay() const {
+    const ash::DisplayManager* const display_manager = GetDisplayManager();
+    if (display_manager->GetNumDisplays() < 2) {
+      ADD_FAILURE()
+          << "Requested rotation of second display while there was only one.";
+      return gfx::Display::ROTATE_0;
+    }
+    const ash::DisplayIdPair display_id_pair =
+        display_manager->GetCurrentDisplayIdPair();
+    const gfx::Display& second_display =
+        display_manager->GetDisplayForId(display_id_pair.second);
+    return second_display.rotation();
+  }
+
+  // Creates second display if there is none yet, or removes it if there is one.
+  void ToggleSecondDisplay() {
+    GetDisplayManager()->AddRemoveDisplay();
+    base::RunLoop run_loop;
+    run_loop.RunUntilIdle();
+  }
+
+  void RefreshPolicyAndWaitUntilDeviceSettingsUpdated() {
+    base::RunLoop run_loop;
+    // For calls from SetPolicy().
+    scoped_ptr<chromeos::CrosSettings::ObserverSubscription> observer =
+        chromeos::CrosSettings::Get()->AddSettingsObserver(
+            chromeos::kDisplayRotationDefault, run_loop.QuitClosure());
+    // For calls from SetADifferentPolicy().
+    scoped_ptr<chromeos::CrosSettings::ObserverSubscription> observer2 =
+        chromeos::CrosSettings::Get()->AddSettingsObserver(
+            chromeos::kSystemUse24HourClock, run_loop.QuitClosure());
+    RefreshDevicePolicy();
+    run_loop.Run();
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(DisplayRotationDefaultTest);
+};
+
+// If gfx::Display::Rotation is ever modified and this test fails, there are
+// hardcoded enum-values in the following files that might need adjustment:
+// * this file: range check in this function, initializations, expected values,
+//              the list of parameters at the bottom of the file
+// * display_rotation_default_handler.cc: Range check in UpdateFromCrosSettings,
+//                                        initialization to ROTATE_0
+// * display_rotation_default_handler.h: initialization to ROTATE_0
+// * chrome/browser/chromeos/policy/proto/chrome_device_policy.proto:
+//       DisplayRotationDefaultProto::Rotation should match one to one
+IN_PROC_BROWSER_TEST_P(DisplayRotationDefaultTest, EnumsInSync) {
+  const gfx::Display::Rotation rotation = GetParam();
+  EXPECT_EQ(em::DisplayRotationDefaultProto::Rotation_ARRAYSIZE,
+            gfx::Display::ROTATE_270 + 1)
+      << "Enums gfx::Display::Rotation and "
+      << "em::DisplayRotationDefaultProto::Rotation are not in sync.";
+  EXPECT_TRUE(em::DisplayRotationDefaultProto::Rotation_IsValid(rotation))
+      << rotation << " is invalid as rotation. All valid values lie in "
+      << "the range from " << em::DisplayRotationDefaultProto::Rotation_MIN
+      << " to " << em::DisplayRotationDefaultProto::Rotation_MAX << ".";
+}
+
+IN_PROC_BROWSER_TEST_P(DisplayRotationDefaultTest, FirstDisplay) {
+  const gfx::Display::Rotation policy_rotation = GetParam();
+  EXPECT_EQ(gfx::Display::ROTATE_0, GetRotationOfFirstDisplay())
+      << "Initial primary rotation before policy";
+
+  SetPolicy(policy_rotation);
+  int settings_rotation;
+  EXPECT_TRUE(chromeos::CrosSettings::Get()->GetInteger(
+      chromeos::kDisplayRotationDefault, &settings_rotation));
+  EXPECT_EQ(policy_rotation, settings_rotation)
+      << "Value of CrosSettings after policy value changed";
+  EXPECT_EQ(policy_rotation, GetRotationOfFirstDisplay())
+      << "Rotation of primary display after policy";
+}
+
+IN_PROC_BROWSER_TEST_P(DisplayRotationDefaultTest, RefreshSecondDisplay) {
+  const gfx::Display::Rotation policy_rotation = GetParam();
+  ToggleSecondDisplay();
+  EXPECT_EQ(gfx::Display::ROTATE_0, GetRotationOfSecondDisplay())
+      << "Rotation of secondary display before policy";
+  SetPolicy(policy_rotation);
+  EXPECT_EQ(policy_rotation, GetRotationOfSecondDisplay())
+      << "Rotation of already connected secondary display after policy";
+}
+
+IN_PROC_BROWSER_TEST_P(DisplayRotationDefaultTest, ConnectSecondDisplay) {
+  const gfx::Display::Rotation policy_rotation = GetParam();
+  SetPolicy(policy_rotation);
+  ToggleSecondDisplay();
+  EXPECT_EQ(policy_rotation, GetRotationOfFirstDisplay())
+      << "Rotation of primary display after policy";
+  EXPECT_EQ(policy_rotation, GetRotationOfSecondDisplay())
+      << "Rotation of newly connected secondary display after policy";
+}
+
+IN_PROC_BROWSER_TEST_P(DisplayRotationDefaultTest, UserInteraction) {
+  const gfx::Display::Rotation policy_rotation = GetParam();
+  const gfx::Display::Rotation user_rotation = gfx::Display::ROTATE_90;
+  GetDisplayManager()->SetDisplayRotation(
+      GetDisplayManager()->first_display_id(), user_rotation,
+      gfx::Display::ROTATION_SOURCE_USER);
+  EXPECT_EQ(user_rotation, GetRotationOfFirstDisplay())
+      << "Rotation of primary display after user change";
+  SetPolicy(policy_rotation);
+  EXPECT_EQ(policy_rotation, GetRotationOfFirstDisplay())
+      << "Rotation of primary display after policy overrode user change";
+  GetDisplayManager()->SetDisplayRotation(
+      GetDisplayManager()->first_display_id(), user_rotation,
+      gfx::Display::ROTATION_SOURCE_USER);
+  EXPECT_EQ(user_rotation, GetRotationOfFirstDisplay())
+      << "Rotation of primary display after user overrode policy change";
+  SetADifferentPolicy();
+  EXPECT_EQ(user_rotation, GetRotationOfFirstDisplay())
+      << "Rotation of primary display after policy reloaded without change";
+}
+
+IN_PROC_BROWSER_TEST_P(DisplayRotationDefaultTest, SetAndUnsetPolicy) {
+  const gfx::Display::Rotation policy_rotation = GetParam();
+  SetPolicy(policy_rotation);
+  UnsetPolicy();
+  EXPECT_EQ(policy_rotation, GetRotationOfFirstDisplay())
+      << "Rotation of primary display after policy was set and removed.";
+}
+
+IN_PROC_BROWSER_TEST_P(DisplayRotationDefaultTest,
+                       SetAndUnsetPolicyWithUserInteraction) {
+  const gfx::Display::Rotation policy_rotation = GetParam();
+  const gfx::Display::Rotation user_rotation = gfx::Display::ROTATE_90;
+  SetPolicy(policy_rotation);
+  GetDisplayManager()->SetDisplayRotation(
+      GetDisplayManager()->first_display_id(), user_rotation,
+      gfx::Display::ROTATION_SOURCE_USER);
+  UnsetPolicy();
+  EXPECT_EQ(user_rotation, GetRotationOfFirstDisplay())
+      << "Rotation of primary display after policy was set to "
+      << policy_rotation << ", user changed the rotation to " << user_rotation
+      << ", and policy was removed.";
+}
+
+INSTANTIATE_TEST_CASE_P(PolicyDisplayRotationDefault,
+                        DisplayRotationDefaultTest,
+                        testing::Values(gfx::Display::ROTATE_0,
+                                        gfx::Display::ROTATE_90,
+                                        gfx::Display::ROTATE_180,
+                                        gfx::Display::ROTATE_270));
+}  // namespace policy
diff --git a/chrome/browser/chromeos/policy/proto/chrome_device_policy.proto b/chrome/browser/chromeos/policy/proto/chrome_device_policy.proto
index 4c20c27..a2a365f 100644
--- a/chrome/browser/chromeos/policy/proto/chrome_device_policy.proto
+++ b/chrome/browser/chromeos/policy/proto/chrome_device_policy.proto
@@ -631,6 +631,23 @@
   optional bool system_log_upload_enabled = 1 [default = false];
 }
 
+// This setting is controlled by the device policy DisplayRotationDefault.
+// If the policy is set and therefore display_rotation_default contains a value,
+// all displays will be rotated clockwise to the specified orientation at
+// reboot, when first connected, or when the setting is changed.
+// If the optional field |Rotation display_rotation_default = 1| is not present,
+// no changes are done to the rotation.
+message DisplayRotationDefaultProto {
+  // This enum corresponds to gfx::Display::Rotation in ui/gfx/display.h.
+  enum Rotation {
+    ROTATE_0 = 0;
+    ROTATE_90 = 1;
+    ROTATE_180 = 2;
+    ROTATE_270 = 3;
+  };
+  optional Rotation display_rotation_default = 1;
+}
+
 message ChromeDeviceSettingsProto {
   optional DevicePolicyRefreshRateProto device_policy_refresh_rate = 1;
   optional UserWhitelistProto user_whitelist = 2;
@@ -674,4 +691,5 @@
   optional LoginScreenDomainAutoCompleteProto
       login_screen_domain_auto_complete = 37;
   optional DeviceLogUploadSettingsProto device_log_upload_settings = 38;
+  optional DisplayRotationDefaultProto display_rotation_default = 39;
 }
diff --git a/chrome/browser/chromeos/policy/user_affiliation_browsertest.cc b/chrome/browser/chromeos/policy/user_affiliation_browsertest.cc
new file mode 100644
index 0000000..8c9e368
--- /dev/null
+++ b/chrome/browser/chromeos/policy/user_affiliation_browsertest.cc
@@ -0,0 +1,93 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/memory/scoped_ptr.h"
+#include "chrome/browser/chromeos/policy/affiliation_test_helper.h"
+#include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h"
+#include "chromeos/dbus/dbus_thread_manager.h"
+#include "chromeos/dbus/fake_session_manager_client.h"
+#include "chromeos/dbus/session_manager_client.h"
+#include "components/user_manager/user.h"
+#include "components/user_manager/user_manager.h"
+#include "content/public/test/test_utils.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace policy {
+
+namespace {
+
+const char kAffiliatedUser[] = "affiliated-user@example.com";
+const char kAffiliationID[] = "some-affiliation-id";
+const char kAnotherAffiliationID[] = "another-affiliation-id";
+struct Params {
+  explicit Params(bool affiliated) : affiliated_(affiliated) {}
+  bool affiliated_;
+};
+
+}  // namespace
+
+class UserAffiliationBrowserTest
+    : public InProcessBrowserTest,
+      public ::testing::WithParamInterface<Params> {
+ public:
+  UserAffiliationBrowserTest() { set_exit_when_last_browser_closes(false); }
+
+ protected:
+  // InProcessBrowserTest
+  void SetUpCommandLine(base::CommandLine* command_line) override {
+    InProcessBrowserTest::SetUpCommandLine(command_line);
+    affiliation_test_helper::AppendCommandLineSwitchesForLoginManager(
+        command_line);
+  }
+
+  // InProcessBrowserTest
+  void SetUpInProcessBrowserTestFixture() override {
+    InProcessBrowserTest::SetUpInProcessBrowserTestFixture();
+
+    chromeos::FakeSessionManagerClient* fake_session_manager_client =
+        new chromeos::FakeSessionManagerClient;
+    chromeos::DBusThreadManager::GetSetterForTesting()->SetSessionManagerClient(
+        make_scoped_ptr<chromeos::SessionManagerClient>(
+            fake_session_manager_client));
+
+    UserPolicyBuilder user_policy;
+    DevicePolicyCrosTestHelper test_helper;
+
+    std::set<std::string> device_affiliation_ids;
+    device_affiliation_ids.insert(kAffiliationID);
+    affiliation_test_helper::SetDeviceAffiliationID(
+        &test_helper, fake_session_manager_client, device_affiliation_ids);
+
+    std::set<std::string> user_affiliation_ids;
+    if (GetParam().affiliated_) {
+      user_affiliation_ids.insert(kAffiliationID);
+    } else {
+      user_affiliation_ids.insert(kAnotherAffiliationID);
+    }
+    affiliation_test_helper::SetUserAffiliationIDs(
+        &user_policy, fake_session_manager_client, kAffiliatedUser,
+        user_affiliation_ids);
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(UserAffiliationBrowserTest);
+};
+
+IN_PROC_BROWSER_TEST_P(UserAffiliationBrowserTest, PRE_Affiliated) {
+  affiliation_test_helper::PreLoginUser(kAffiliatedUser);
+}
+
+IN_PROC_BROWSER_TEST_P(UserAffiliationBrowserTest, Affiliated) {
+  affiliation_test_helper::LoginUser(kAffiliatedUser);
+  EXPECT_EQ(GetParam().affiliated_,
+            user_manager::UserManager::Get()
+                ->FindUser(AccountId::FromUserEmail(kAffiliatedUser))
+                ->is_affiliated());
+}
+
+INSTANTIATE_TEST_CASE_P(AffiliationCheck,
+                        UserAffiliationBrowserTest,
+                        ::testing::Values(Params(true), Params(false)));
+
+}  // namespace policy
diff --git a/chrome/browser/chromeos/proxy_config_service_impl.cc b/chrome/browser/chromeos/proxy_config_service_impl.cc
index d5b69a6..4e63069 100644
--- a/chrome/browser/chromeos/proxy_config_service_impl.cc
+++ b/chrome/browser/chromeos/proxy_config_service_impl.cc
@@ -13,7 +13,6 @@
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/chromeos/net/proxy_config_handler.h"
-#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
 #include "chrome/common/pref_names.h"
 #include "chromeos/network/network_profile.h"
 #include "chromeos/network/network_profile_handler.h"
@@ -152,12 +151,9 @@
     return false;
   }
   if (onc_source == ::onc::ONC_SOURCE_DEVICE_POLICY) {
-    policy::BrowserPolicyConnectorChromeOS* connector =
-        g_browser_process->platform_part()->browser_policy_connector_chromeos();
     const user_manager::User* logged_in_user =
         user_manager::UserManager::Get()->GetLoggedInUser();
-    if (connector->GetUserAffiliation(logged_in_user->email()) ==
-        policy::USER_AFFILIATION_MANAGED) {
+    if (logged_in_user->is_affiliated()) {
       VLOG(1) << "Respecting proxy for network, as logged-in user belongs to "
               << "the domain the device is enrolled to.";
       return false;
diff --git a/chrome/browser/chromeos/settings/device_settings_provider.cc b/chrome/browser/chromeos/settings/device_settings_provider.cc
index 6cf0395..df7694f37 100644
--- a/chrome/browser/chromeos/settings/device_settings_provider.cc
+++ b/chrome/browser/chromeos/settings/device_settings_provider.cc
@@ -59,6 +59,7 @@
     kDeviceDisabled,
     kDeviceDisabledMessage,
     kDeviceOwner,
+    kDisplayRotationDefault,
     kExtensionCacheSize,
     kHeartbeatEnabled,
     kHeartbeatFrequency,
@@ -440,6 +441,13 @@
         kExtensionCacheSize,
         policy.extension_cache_size().extension_cache_size());
   }
+
+  if (policy.has_display_rotation_default() &&
+      policy.display_rotation_default().has_display_rotation_default()) {
+    new_values_cache->SetInteger(
+        kDisplayRotationDefault,
+        policy.display_rotation_default().display_rotation_default());
+  }
 }
 
 void DecodeLogUploadPolicies(const em::ChromeDeviceSettingsProto& policy,
diff --git a/chrome/browser/component_updater/supervised_user_whitelist_installer.cc b/chrome/browser/component_updater/supervised_user_whitelist_installer.cc
index 61e3841..a266eec 100644
--- a/chrome/browser/component_updater/supervised_user_whitelist_installer.cc
+++ b/chrome/browser/component_updater/supervised_user_whitelist_installer.cc
@@ -24,6 +24,7 @@
 #include "base/thread_task_runner_handle.h"
 #include "chrome/browser/profiles/profile_info_cache.h"
 #include "chrome/browser/profiles/profile_info_cache_observer.h"
+#include "chrome/browser/supervised_user/supervised_user_whitelist_service.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/pref_names.h"
 #include "components/component_updater/component_updater_paths.h"
@@ -386,29 +387,42 @@
 }
 
 void SupervisedUserWhitelistInstallerImpl::RegisterComponents() {
+  const std::map<std::string, std::string> command_line_whitelists =
+      SupervisedUserWhitelistService::GetWhitelistsFromCommandLine();
+
   std::set<std::string> registered_whitelists;
-  const base::DictionaryValue* whitelists =
-      local_state_->GetDictionary(prefs::kRegisteredSupervisedUserWhitelists);
+  std::set<std::string> stale_whitelists;
+  DictionaryPrefUpdate update(local_state_,
+                              prefs::kRegisteredSupervisedUserWhitelists);
+  base::DictionaryValue* whitelists = update.Get();
   for (base::DictionaryValue::Iterator it(*whitelists); !it.IsAtEnd();
        it.Advance()) {
     const base::DictionaryValue* dict = nullptr;
     it.value().GetAsDictionary(&dict);
 
+    const std::string& id = it.key();
+
     // Skip whitelists with no clients. This can happen when a whitelist was
-    // previously registered with an empty client ID.
+    // previously registered on the command line but isn't anymore.
     const base::ListValue* clients = nullptr;
-    if (!dict->GetList(kClients, &clients) || clients->empty())
+    if ((!dict->GetList(kClients, &clients) || clients->empty()) &&
+        command_line_whitelists.count(id) == 0) {
+      stale_whitelists.insert(id);
       continue;
+    }
 
     std::string name;
     bool result = dict->GetString(kName, &name);
     DCHECK(result);
-    const std::string& id = it.key();
     RegisterComponent(id, name, base::Closure());
 
     registered_whitelists.insert(id);
   }
 
+  // Clean up stale whitelists as determined above.
+  for (const std::string& id : stale_whitelists)
+    whitelists->RemoveWithoutPathExpansion(id, nullptr);
+
   cus_->GetSequencedTaskRunner()->PostTask(
       FROM_HERE, base::Bind(&RemoveUnregisteredWhitelistsOnTaskRunner,
                             registered_whitelists));
diff --git a/chrome/browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_api.cc b/chrome/browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_api.cc
index fe3bc1b..a0024f73 100644
--- a/chrome/browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_api.cc
+++ b/chrome/browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_api.cc
@@ -17,19 +17,12 @@
 
 namespace {
 
-// Checks for the current browser context if the user is affiliated and the
-// device is enterprise managed.
+// Checks for the current browser context if the user is affiliated.
 bool IsPermittedToGetDeviceId(content::BrowserContext* context) {
-  policy::BrowserPolicyConnectorChromeOS* connector =
-      g_browser_process->platform_part()->browser_policy_connector_chromeos();
-
   const user_manager::User* user =
       chromeos::ProfileHelper::Get()->GetUserByProfile(
           Profile::FromBrowserContext(context));
-
-  return connector->IsEnterpriseManaged() &&
-         connector->GetUserAffiliation(user->email()) ==
-             policy::USER_AFFILIATION_MANAGED;
+  return user->is_affiliated();
 }
 
 // Returns the directory device id for the permitted extensions or an empty
diff --git a/chrome/browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_apitest.cc b/chrome/browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_apitest.cc
index 19d0ebf..685e0d7 100644
--- a/chrome/browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_apitest.cc
+++ b/chrome/browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_apitest.cc
@@ -2,22 +2,27 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "base/prefs/pref_service.h"
 #include "base/strings/stringprintf.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/chromeos/policy/affiliation_test_helper.h"
 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
 #include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h"
 #include "chrome/browser/chromeos/policy/stub_enterprise_install_attributes.h"
 #include "chrome/browser/extensions/extension_apitest.h"
 #include "chrome/browser/net/url_request_mock_util.h"
+#include "chrome/test/base/ui_test_utils.h"
 #include "chromeos/dbus/fake_session_manager_client.h"
 #include "chromeos/login/user_names.h"
 #include "components/policy/core/common/mock_configuration_policy_provider.h"
-#include "components/policy/core/common/policy_types.h"
 #include "components/signin/core/account_id/account_id.h"
+#include "components/user_manager/user_manager.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/test/test_utils.h"
 #include "extensions/browser/api_test_utils.h"
 #include "extensions/browser/extension_registry.h"
 #include "extensions/browser/test_extension_registry_observer.h"
+#include "extensions/test/result_catcher.h"
 #include "net/test/url_request/url_request_mock_http_job.h"
 #include "policy/policy_constants.h"
 
@@ -29,34 +34,71 @@
 const base::FilePath::CharType kUpdateManifestFileName[] =
     FILE_PATH_LITERAL("update_manifest.xml");
 
+const char kAffiliatedUserEmail[] = "user@example.com";
+const char kAffiliationID[] = "some-affiliation-id";
+const char kAnotherAffiliationID[] = "another-affiliation-id";
+
 // The managed_storage extension has a key defined in its manifest, so that
 // its extension ID is well-known and the policy system can push policies for
 // the extension.
 const char kTestExtensionID[] = "nbiliclbejdndfpchgkbmfoppjplbdok";
 
+struct Params {
+  explicit Params(bool affiliated) : affiliated_(affiliated) {}
+  bool affiliated_;
+};
+
 }  // namespace
 
 namespace extensions {
 
-class EnterpriseDeviceAttributesTest : public ExtensionApiTest {
+class EnterpriseDeviceAttributesTest :
+    public ExtensionApiTest,
+    public ::testing::WithParamInterface<Params> {
  public:
-  explicit EnterpriseDeviceAttributesTest(const std::string& domain)
-      : fake_session_manager_client_(new chromeos::FakeSessionManagerClient),
-        test_domain_(domain) {}
+  EnterpriseDeviceAttributesTest() {
+    set_exit_when_last_browser_closes(false);
+    set_chromeos_user_ = false;
+  }
 
  protected:
+  // ExtensionApiTest
+  void SetUpCommandLine(base::CommandLine* command_line) override {
+    ExtensionApiTest::SetUpCommandLine(command_line);
+    policy::affiliation_test_helper::
+      AppendCommandLineSwitchesForLoginManager(command_line);
+  }
+
   void SetUpInProcessBrowserTestFixture() override {
-    chromeos::DBusThreadManager::GetSetterForTesting()->SetSessionManagerClient(
-        make_scoped_ptr(fake_session_manager_client_));
     ExtensionApiTest::SetUpInProcessBrowserTestFixture();
 
+    chromeos::FakeSessionManagerClient* fake_session_manager_client =
+        new chromeos::FakeSessionManagerClient;
+    chromeos::DBusThreadManager::GetSetterForTesting()->SetSessionManagerClient(
+        scoped_ptr<chromeos::SessionManagerClient>(
+            fake_session_manager_client));
+
+    std::set<std::string> device_affiliation_ids;
+    device_affiliation_ids.insert(kAffiliationID);
+    policy::affiliation_test_helper::SetDeviceAffiliationID(
+        &test_helper_, fake_session_manager_client, device_affiliation_ids);
+
+    std::set<std::string> user_affiliation_ids;
+    if (GetParam().affiliated_) {
+      user_affiliation_ids.insert(kAffiliationID);
+    } else {
+      user_affiliation_ids.insert(kAnotherAffiliationID);
+    }
+    policy::UserPolicyBuilder user_policy;
+    policy::affiliation_test_helper::SetUserAffiliationIDs(
+        &user_policy, fake_session_manager_client,
+        affiliated_account_id_.GetUserEmail(), user_affiliation_ids);
+
     // Set up fake install attributes.
     scoped_ptr<policy::StubEnterpriseInstallAttributes> attributes(
         new policy::StubEnterpriseInstallAttributes());
 
-    attributes->SetDomain(test_domain_);
-    attributes->SetRegistrationUser(
-        chromeos::login::StubAccountId().GetUserEmail());
+    attributes->SetRegistrationUser(affiliated_account_id_.GetUserEmail());
     policy::BrowserPolicyConnectorChromeOS::SetInstallAttributesForTesting(
         attributes.release());
 
@@ -67,8 +109,8 @@
     device_policy->policy_data().set_directory_api_id(kDeviceId);
     device_policy->Build();
 
-    fake_session_manager_client_->set_device_policy(device_policy->GetBlob());
-    fake_session_manager_client_->OnPropertyChangeComplete(true);
+    fake_session_manager_client->set_device_policy(device_policy->GetBlob());
+    fake_session_manager_client->OnPropertyChangeComplete(true);
 
     // Init the user policy provider.
     EXPECT_CALL(policy_provider_, IsInitializationComplete(testing::_))
@@ -79,18 +121,16 @@
   }
 
   void SetUpOnMainThread() override {
+    const base::ListValue* users =
+        g_browser_process->local_state()->GetList("LoggedInUsers");
+    if (!users->empty()) {
+      policy::affiliation_test_helper::LoginUser(
+          affiliated_account_id_.GetUserEmail());
+    }
+
     ExtensionApiTest::SetUpOnMainThread();
-
-    // Enable the URLRequestMock, which is required for force-installing the
-    // test extension through policy.
-    content::BrowserThread::PostTask(
-        content::BrowserThread::IO, FROM_HERE,
-        base::Bind(chrome_browser_net::SetUrlRequestMocksEnabled, true));
-
-    SetPolicy();
   }
 
- private:
   void SetPolicy() {
     // Extensions that are force-installed come from an update URL, which
     // defaults to the webstore. Use a mock URL for this test with an update
@@ -116,46 +156,59 @@
     observer.WaitForExtensionLoaded();
   }
 
-  chromeos::FakeSessionManagerClient* const fake_session_manager_client_;
+  // Load |page_url| in |browser| and wait for PASSED or FAILED notification.
+  // The functionality of this function is reduced functionality of
+  // RunExtensionSubtest(), but we don't use it here because it requires
+  // function InProcessBrowserTest::browser() to return non-NULL pointer.
+  // Unfortunately it returns the value which is set in constructor and can't be
+  // modified. Because on login flow there is no browser, the function
+  // InProcessBrowserTest::browser() always returns NULL. Besides this we need
+  // only very little functionality from RunExtensionSubtest(). Thus so that
+  // don't make RunExtensionSubtest() to complex we just introduce a new
+  // function.
+  bool TestExtension(Browser* browser, const std::string& page_url) {
+    DCHECK(!page_url.empty()) << "page_url cannot be empty";
+
+    extensions::ResultCatcher catcher;
+    ui_test_utils::NavigateToURL(browser, GURL(page_url));
+
+    if (!catcher.GetNextResult()) {
+      message_ = catcher.message();
+      return false;
+    }
+    return true;
+  }
+
+  const AccountId affiliated_account_id_ =
+      AccountId::FromUserEmail(kAffiliatedUserEmail);
+
+ private:
   policy::MockConfigurationPolicyProvider policy_provider_;
   policy::DevicePolicyCrosTestHelper test_helper_;
-  const std::string test_domain_;
 };
 
-// Creates affiliated user before browser initializes.
-class EnterpriseDeviceAttributesAffiliatedTest
-    : public EnterpriseDeviceAttributesTest {
- public:
-  EnterpriseDeviceAttributesAffiliatedTest()
-      : EnterpriseDeviceAttributesTest("gmail.com") {}
-};
-
-// Creates non-affiliated user before browser init.
-class EnterpriseDeviceAttributesNonAffiliatedTest
-    : public EnterpriseDeviceAttributesTest {
- public:
-  EnterpriseDeviceAttributesNonAffiliatedTest()
-      : EnterpriseDeviceAttributesTest("example.com") {}
-};
-
-// Tests the case of an affiliated user and pre-installed extension. Fetches
-// the valid cloud directory device id.
-IN_PROC_BROWSER_TEST_F(EnterpriseDeviceAttributesAffiliatedTest, Success) {
-  // Pass the expected value (device_id) to test.
-  ASSERT_TRUE(RunExtensionSubtest(
-      "", base::StringPrintf("chrome-extension://%s/basic.html?%s",
-                             kTestExtensionID, kDeviceId)))
-      << message_;
+IN_PROC_BROWSER_TEST_P(EnterpriseDeviceAttributesTest, PRE_Success) {
+  policy::affiliation_test_helper::PreLoginUser(
+      affiliated_account_id_.GetUserEmail());
 }
 
-// Test the case of non-affiliated user and pre-installed by policy extension.
-// Extension API is available, but fetches the empty string.
-IN_PROC_BROWSER_TEST_F(EnterpriseDeviceAttributesNonAffiliatedTest,
-                       EmptyString) {
-  // Pass the expected value (empty string) to test.
-  ASSERT_TRUE(RunExtensionSubtest(
-      "", base::StringPrintf("chrome-extension://%s/basic.html?%s",
-                             kTestExtensionID, "")))
+IN_PROC_BROWSER_TEST_P(EnterpriseDeviceAttributesTest, Success) {
+  content::BrowserThread::PostTask(
+      content::BrowserThread::IO, FROM_HERE,
+      base::Bind(chrome_browser_net::SetUrlRequestMocksEnabled, true));
+
+  SetPolicy();
+
+  EXPECT_EQ(GetParam().affiliated_, user_manager::UserManager::Get()->
+      FindUser(affiliated_account_id_)->is_affiliated());
+
+  // Device ID is available only for affiliated user.
+  std::string device_id = GetParam().affiliated_ ? kDeviceId : "";
+
+  // Pass the expected value (device_id) to test.
+  ASSERT_TRUE(TestExtension(CreateBrowser(profile()),
+      base::StringPrintf("chrome-extension://%s/basic.html?%s",
+                             kTestExtensionID, device_id.c_str())))
       << message_;
 }
 
@@ -183,4 +236,8 @@
       extension->install_warnings()[0].message);
 }
 
+// Both cases of affiliated and non-affiliated on the device user are tested.
+INSTANTIATE_TEST_CASE_P(AffiliationCheck,
+                          EnterpriseDeviceAttributesTest,
+                        ::testing::Values(Params(true), Params(false)));
 }  //  namespace extensions
diff --git a/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_apitest_nss.cc b/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_apitest_nss.cc
index c936d30..acbdb81 100644
--- a/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_apitest_nss.cc
+++ b/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_apitest_nss.cc
@@ -5,29 +5,51 @@
 #include <cryptohi.h>
 
 #include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/path_service.h"
+#include "base/prefs/pref_service.h"
 #include "base/strings/stringprintf.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/chromeos/login/test/https_forwarder.h"
+#include "chrome/browser/chromeos/policy/affiliation_test_helper.h"
 #include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h"
 #include "chrome/browser/extensions/extension_apitest.h"
 #include "chrome/browser/net/nss_context.h"
 #include "chrome/browser/net/url_request_mock_util.h"
+#include "chrome/common/chrome_paths.h"
+#include "chrome/test/base/ui_test_utils.h"
 #include "chromeos/chromeos_switches.h"
+#include "chromeos/dbus/dbus_thread_manager.h"
+#include "chromeos/dbus/fake_session_manager_client.h"
+#include "chromeos/dbus/session_manager_client.h"
 #include "chromeos/login/user_names.h"
 #include "components/policy/core/browser/browser_policy_connector.h"
 #include "components/policy/core/common/mock_configuration_policy_provider.h"
 #include "components/policy/core/common/policy_map.h"
-#include "components/policy/core/common/policy_types.h"
 #include "components/signin/core/account_id/account_id.h"
+#include "components/user_manager/user_manager.h"
 #include "content/public/common/content_switches.h"
-#include "content/public/test/test_utils.h"
 #include "crypto/nss_util_internal.h"
 #include "crypto/scoped_test_system_nss_key_slot.h"
 #include "extensions/browser/extension_registry.h"
 #include "extensions/browser/test_extension_registry_observer.h"
+#include "extensions/browser/test_extension_registry_observer.h"
+#include "extensions/test/result_catcher.h"
+#include "google_apis/gaia/fake_gaia.h"
+#include "google_apis/gaia/gaia_constants.h"
+#include "google_apis/gaia/gaia_switches.h"
+#include "google_apis/gaia/gaia_urls.h"
 #include "net/base/net_errors.h"
 #include "net/cert/nss_cert_database.h"
+#include "net/dns/mock_host_resolver.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "net/test/embedded_test_server/http_request.h"
+#include "net/test/embedded_test_server/http_response.h"
 #include "net/test/url_request/url_request_mock_http_job.h"
 #include "policy/policy_constants.h"
 #include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
 
 namespace {
 
@@ -134,6 +156,10 @@
 // its extension ID is well-known and the policy system can push policies for
 // the extension.
 const char kTestExtensionID[] = "aecpbnckhoppanpmefllkdkohionpmig";
+const char kAffiliationID[] = "some-affiliation-id";
+const char kTestUserinfoToken[] = "fake-userinfo-token";
+
+using policy::affiliation_test_helper::kEnterpriseUser;
 
 enum SystemToken {
   SYSTEM_TOKEN_EXISTS,
@@ -167,7 +193,34 @@
     : public ExtensionApiTest,
       public ::testing::WithParamInterface<Params> {
  public:
-  EnterprisePlatformKeysTest() {}
+  EnterprisePlatformKeysTest() {
+    // Command line should not be tweaked as if user is already logged in.
+    set_chromeos_user_ = false;
+    // We log in without running browser.
+    set_exit_when_last_browser_closes(false);
+  }
+
+  void SetUp() override {
+    base::FilePath test_data_dir;
+    PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir);
+    embedded_test_server()->ServeFilesFromDirectory(test_data_dir);
+
+    embedded_test_server()->RegisterRequestHandler(
+        base::Bind(&FakeGaia::HandleRequest,
+                   base::Unretained(&fake_gaia_)));
+
+    // Don't spin up the IO thread yet since no threads are allowed while
+    // spawning sandbox host process. See crbug.com/322732.
+    ASSERT_TRUE(embedded_test_server()->InitializeAndListen());
+
+    // Start https wrapper here so that the URLs can be pointed at it in
+    // SetUpCommandLine().
+    ASSERT_TRUE(gaia_https_forwarder_.Initialize(
+        GaiaUrls::GetInstance()->gaia_url().host(),
+        embedded_test_server()->base_url()));
+
+    ExtensionApiTest::SetUp();
+  }
 
   void SetUpCommandLine(base::CommandLine* command_line) override {
     ExtensionApiTest::SetUpCommandLine(command_line);
@@ -176,27 +229,49 @@
     command_line->AppendSwitch(
         switches::kEnableExperimentalWebPlatformFeatures);
 
-    std::string user_email = "someuser@anydomain.com";
+    policy::affiliation_test_helper::
+      AppendCommandLineSwitchesForLoginManager(command_line);
 
-    // The command line flag kLoginUser determines the user's email and thus
-    // his affiliation to the domain that the device is enrolled to.
-    if (GetParam().user_affiliation_ == USER_AFFILIATION_ENROLLED_DOMAIN)
-      user_email = chromeos::login::StubAccountId().GetUserEmail();
+    const GURL gaia_url = gaia_https_forwarder_.GetURLForSSLHost(std::string());
+    command_line->AppendSwitchASCII(::switches::kGaiaUrl, gaia_url.spec());
+    command_line->AppendSwitchASCII(::switches::kLsoUrl, gaia_url.spec());
+    command_line->AppendSwitchASCII(::switches::kGoogleApisUrl,
+                                    gaia_url.spec());
 
-    command_line->AppendSwitchASCII(chromeos::switches::kLoginUser, user_email);
+    fake_gaia_.Initialize();
+    fake_gaia_.set_issue_oauth_code_cookie(true);
   }
 
   void SetUpInProcessBrowserTestFixture() override {
     ExtensionApiTest::SetUpInProcessBrowserTestFixture();
 
-    if (GetParam().device_status_ == DEVICE_STATUS_ENROLLED) {
-      device_policy_test_helper_.device_policy()->policy_data().set_username(
-          chromeos::login::StubAccountId().GetUserEmail());
+    host_resolver()->AddRule("*", "127.0.0.1");
 
-      device_policy_test_helper_.device_policy()->Build();
-      device_policy_test_helper_.MarkAsEnterpriseOwned();
+    chromeos::FakeSessionManagerClient* fake_session_manager_client =
+        new chromeos::FakeSessionManagerClient;
+    chromeos::DBusThreadManager::GetSetterForTesting()->SetSessionManagerClient(
+        scoped_ptr<chromeos::SessionManagerClient>(
+            fake_session_manager_client));
+
+    if (GetParam().device_status_ == DEVICE_STATUS_ENROLLED) {
+      std::set<std::string> device_affiliation_ids;
+      device_affiliation_ids.insert(kAffiliationID);
+      policy::affiliation_test_helper::SetDeviceAffiliationID(
+          &device_policy_test_helper_, fake_session_manager_client,
+          device_affiliation_ids);
     }
 
+
+    if (GetParam().user_affiliation_ == USER_AFFILIATION_ENROLLED_DOMAIN) {
+      std::set<std::string> user_affiliation_ids;
+      user_affiliation_ids.insert(kAffiliationID);
+      policy::UserPolicyBuilder user_policy;
+      policy::affiliation_test_helper::SetUserAffiliationIDs(
+          &user_policy, fake_session_manager_client, kEnterpriseUser,
+          user_affiliation_ids);
+    }
+
+
     EXPECT_CALL(policy_provider_, IsInitializationComplete(testing::_))
         .WillRepeatedly(testing::Return(true));
     policy_provider_.SetAutoRefresh();
@@ -205,6 +280,31 @@
   }
 
   void SetUpOnMainThread() override {
+    // Start the accept thread as the sandbox host process has already been
+    // spawned.
+    embedded_test_server()->StartAcceptingConnections();
+
+    FakeGaia::AccessTokenInfo token_info;
+    token_info.scopes.insert(GaiaConstants::kDeviceManagementServiceOAuth);
+    token_info.scopes.insert(GaiaConstants::kOAuthWrapBridgeUserInfoScope);
+    token_info.audience = GaiaUrls::GetInstance()->oauth2_chrome_client_id();
+    token_info.token = kTestUserinfoToken;
+    token_info.email = kEnterpriseUser;
+    fake_gaia_.IssueOAuthToken(
+        policy::affiliation_test_helper::kFakeRefreshToken,
+        token_info);
+
+    // On PRE_ test stage list of users is empty at this point. Then in the body
+    // of PRE_ test kEnterpriseUser is added. Afterwards in the main test flow
+    // after PRE_ test the list of user contains one kEnterpriseUser user.
+    // This user logs in.
+    const base::ListValue* users =
+        g_browser_process->local_state()->GetList("LoggedInUsers");
+
+    // This condition is not held in PRE_ test.
+    if (!users->empty())
+      policy::affiliation_test_helper::LoginUser(kEnterpriseUser);
+
     if (GetParam().system_token_ == SYSTEM_TOKEN_EXISTS) {
       base::RunLoop loop;
       content::BrowserThread::PostTask(
@@ -212,31 +312,11 @@
           FROM_HERE,
           base::Bind(&EnterprisePlatformKeysTest::SetUpTestSystemSlotOnIO,
                      base::Unretained(this),
-                     browser()->profile()->GetResourceContext(),
                      loop.QuitClosure()));
       loop.Run();
     }
 
     ExtensionApiTest::SetUpOnMainThread();
-
-    // Enable the URLRequestMock, which is required for force-installing the
-    // test extension through policy.
-    content::BrowserThread::PostTask(
-        content::BrowserThread::IO,
-        FROM_HERE,
-        base::Bind(chrome_browser_net::SetUrlRequestMocksEnabled, true));
-
-    {
-      base::RunLoop loop;
-      GetNSSCertDatabaseForProfile(
-          browser()->profile(),
-          base::Bind(&EnterprisePlatformKeysTest::DidGetCertDatabase,
-                     base::Unretained(this),
-                     loop.QuitClosure()));
-      loop.Run();
-    }
-
-    SetPolicy();
   }
 
   void TearDownOnMainThread() override {
@@ -252,9 +332,9 @@
                      loop.QuitClosure()));
       loop.Run();
     }
+    EXPECT_TRUE(embedded_test_server()->ShutdownAndWaitUntilComplete());
   }
 
- private:
   void DidGetCertDatabase(const base::Closure& done_callback,
                           net::NSSCertDatabase* cert_db) {
     // In order to use a prepared certificate, import a private key to the
@@ -265,28 +345,6 @@
     done_callback.Run();
   }
 
-  void SetUpTestSystemSlotOnIO(content::ResourceContext* context,
-                               const base::Closure& done_callback) {
-    test_system_slot_.reset(new crypto::ScopedTestSystemNSSKeySlot());
-    ASSERT_TRUE(test_system_slot_->ConstructedSuccessfully());
-
-    // Import a private key to the system slot.  The Javascript part of this
-    // test has a prepared certificate for this key.
-    ImportPrivateKeyPKCS8ToSlot(privateKeyPkcs8System,
-                                arraysize(privateKeyPkcs8System),
-                                test_system_slot_->slot());
-
-    content::BrowserThread::PostTask(
-        content::BrowserThread::UI, FROM_HERE, done_callback);
-  }
-
-  void TearDownTestSystemSlotOnIO(const base::Closure& done_callback) {
-    test_system_slot_.reset();
-
-    content::BrowserThread::PostTask(
-        content::BrowserThread::UI, FROM_HERE, done_callback);
-  }
-
   void SetPolicy() {
     // Extensions that are force-installed come from an update URL, which
     // defaults to the webstore. Use a mock URL for this test with an update
@@ -315,14 +373,84 @@
     observer.WaitForExtensionWillBeInstalled();
   }
 
+  // Load |page_url| in |browser| and wait for PASSED or FAILED notification.
+  // The functionality of this function is reduced functionality of
+  // RunExtensionSubtest(), but we don't use it here because it requires
+  // function InProcessBrowserTest::browser() to return non-NULL pointer.
+  // Unfortunately it returns the value which is set in constructor and can't be
+  // modified. Because on login flow there is no browser, the function
+  // InProcessBrowserTest::browser() always returns NULL. Besides this we need
+  // only very little functionality from RunExtensionSubtest(). Thus so that
+  // don't make RunExtensionSubtest() to complex we just introduce a new
+  // function.
+  bool TestExtension(Browser* browser, const std::string& page_url) {
+    DCHECK(!page_url.empty()) << "page_url cannot be empty";
+
+    extensions::ResultCatcher catcher;
+    ui_test_utils::NavigateToURL(browser, GURL(page_url));
+
+    if (!catcher.GetNextResult()) {
+      message_ = catcher.message();
+      return false;
+    }
+    return true;
+  }
+
+ private:
+
+  void SetUpTestSystemSlotOnIO(const base::Closure& done_callback) {
+    test_system_slot_.reset(new crypto::ScopedTestSystemNSSKeySlot());
+    ASSERT_TRUE(test_system_slot_->ConstructedSuccessfully());
+
+    // Import a private key to the system slot.  The Javascript part of this
+    // test has a prepared certificate for this key.
+    ImportPrivateKeyPKCS8ToSlot(privateKeyPkcs8System,
+                                arraysize(privateKeyPkcs8System),
+                                test_system_slot_->slot());
+
+    content::BrowserThread::PostTask(
+        content::BrowserThread::UI, FROM_HERE, done_callback);
+  }
+
+  void TearDownTestSystemSlotOnIO(const base::Closure& done_callback) {
+    test_system_slot_.reset();
+
+    content::BrowserThread::PostTask(
+        content::BrowserThread::UI, FROM_HERE, done_callback);
+  }
+
   policy::DevicePolicyCrosTestHelper device_policy_test_helper_;
   scoped_ptr<crypto::ScopedTestSystemNSSKeySlot> test_system_slot_;
   policy::MockConfigurationPolicyProvider policy_provider_;
+  FakeGaia fake_gaia_;
+  chromeos::HTTPSForwarder gaia_https_forwarder_;
 };
 
 }  // namespace
 
+IN_PROC_BROWSER_TEST_P(EnterprisePlatformKeysTest, PRE_Basic) {
+  policy::affiliation_test_helper::PreLoginUser(kEnterpriseUser);
+}
+
 IN_PROC_BROWSER_TEST_P(EnterprisePlatformKeysTest, Basic) {
+  // Enable the URLRequestMock, which is required for force-installing the
+  // test extension through policy.
+  content::BrowserThread::PostTask(
+     content::BrowserThread::IO,
+     FROM_HERE,
+     base::Bind(chrome_browser_net::SetUrlRequestMocksEnabled, true));
+
+  {
+   base::RunLoop loop;
+   GetNSSCertDatabaseForProfile(
+       profile(),
+       base::Bind(&EnterprisePlatformKeysTest::DidGetCertDatabase,
+                  base::Unretained(this),
+                  loop.QuitClosure()));
+   loop.Run();
+  }
+  SetPolicy();
+
   // By default, the system token is disabled.
   std::string system_token_availability = "";
 
@@ -335,8 +463,7 @@
     system_token_availability = "systemTokenEnabled";
   }
 
-  ASSERT_TRUE(RunExtensionSubtest(
-      "",
+  ASSERT_TRUE(TestExtension(CreateBrowser(profile()),
       base::StringPrintf("chrome-extension://%s/basic.html?%s",
                          kTestExtensionID,
                          system_token_availability.c_str())))
diff --git a/chrome/browser/extensions/api/image_writer_private/operation.cc b/chrome/browser/extensions/api/image_writer_private/operation.cc
index 0fec496..5c4ce7c5 100644
--- a/chrome/browser/extensions/api/image_writer_private/operation.cc
+++ b/chrome/browser/extensions/api/image_writer_private/operation.cc
@@ -11,6 +11,7 @@
 #include "chrome/browser/extensions/api/image_writer_private/error_messages.h"
 #include "chrome/browser/extensions/api/image_writer_private/operation_manager.h"
 #include "content/public/browser/browser_thread.h"
+#include "third_party/zlib/google/zip_reader.h"
 
 namespace extensions {
 namespace image_writer {
@@ -41,7 +42,8 @@
       device_path_(device_path),
 #endif
       stage_(image_writer_api::STAGE_UNKNOWN),
-      progress_(0) {
+      progress_(0),
+      zip_reader_(new zip::ZipReader) {
 }
 
 Operation::~Operation() {}
@@ -105,20 +107,20 @@
 
   SetStage(image_writer_api::STAGE_UNZIP);
 
-  if (!(zip_reader_.Open(image_path_) && zip_reader_.AdvanceToNextEntry() &&
-        zip_reader_.OpenCurrentEntryInZip())) {
+  if (!(zip_reader_->Open(image_path_) && zip_reader_->AdvanceToNextEntry() &&
+        zip_reader_->OpenCurrentEntryInZip())) {
     Error(error::kUnzipGenericError);
     return;
   }
 
-  if (zip_reader_.HasMore()) {
+  if (zip_reader_->HasMore()) {
     Error(error::kUnzipInvalidArchive);
     return;
   }
 
   // Create a new target to unzip to.  The original file is opened by the
   // zip_reader_.
-  zip::ZipReader::EntryInfo* entry_info = zip_reader_.current_entry_info();
+  zip::ZipReader::EntryInfo* entry_info = zip_reader_->current_entry_info();
   if (entry_info) {
     image_path_ = temp_dir_.path().Append(entry_info->file_path().BaseName());
   } else {
@@ -126,13 +128,13 @@
     return;
   }
 
-  zip_reader_.ExtractCurrentEntryToFilePathAsync(
+  zip_reader_->ExtractCurrentEntryToFilePathAsync(
       image_path_,
       base::Bind(&Operation::CompleteAndContinue, this, continuation),
       base::Bind(&Operation::OnUnzipFailure, this),
       base::Bind(&Operation::OnUnzipProgress,
                  this,
-                 zip_reader_.current_entry_info()->original_size()));
+                 zip_reader_->current_entry_info()->original_size()));
 }
 
 void Operation::Finish() {
diff --git a/chrome/browser/extensions/api/image_writer_private/operation.h b/chrome/browser/extensions/api/image_writer_private/operation.h
index f4e025d..bb0afbc2 100644
--- a/chrome/browser/extensions/api/image_writer_private/operation.h
+++ b/chrome/browser/extensions/api/image_writer_private/operation.h
@@ -14,7 +14,7 @@
 #include "base/task/cancelable_task_tracker.h"
 #include "chrome/browser/extensions/api/image_writer_private/image_writer_utility_client.h"
 #include "chrome/common/extensions/api/image_writer_private.h"
-#include "third_party/zlib/google/zip_reader.h"
+
 
 namespace image_writer_api = extensions::api::image_writer_private;
 
@@ -22,6 +22,10 @@
 class FilePath;
 }  // namespace base
 
+namespace zip {
+class ZipReader;
+}
+
 namespace extensions {
 namespace image_writer {
 
@@ -207,8 +211,10 @@
   // memory here.  This requires that we only do one MD5 sum at a time.
   base::MD5Context md5_context_;
 
-  // Zip reader for unzip operations.
-  zip::ZipReader zip_reader_;
+  // Zip reader for unzip operations. The reason for using a pointer is that we
+  // don't want to include zip_reader.h here which can mangle definitions in
+  // jni.h when included in the same file. See crbug.com/554199.
+  scoped_ptr<zip::ZipReader> zip_reader_;
 
   // CleanUp operations that must be run.  All these functions are run on the
   // FILE thread.
diff --git a/chrome/browser/memory/tab_manager_web_contents_data.cc b/chrome/browser/memory/tab_manager_web_contents_data.cc
index b33f220..4338a21 100644
--- a/chrome/browser/memory/tab_manager_web_contents_data.cc
+++ b/chrome/browser/memory/tab_manager_web_contents_data.cc
@@ -52,14 +52,22 @@
 void TabManager::WebContentsData::SetDiscardState(bool state) {
   if (tab_data_.is_discarded_ && !state) {
     static int reload_count = 0;
+    tab_data_.last_reload_time_ = NowTicks();
     UMA_HISTOGRAM_CUSTOM_COUNTS("TabManager.Discarding.ReloadCount",
                                 ++reload_count, 1, 1000, 50);
-    auto delta = NowTicks() - tab_data_.last_discard_time_;
+    auto delta = tab_data_.last_reload_time_ - tab_data_.last_discard_time_;
     // Capped to one day for now, will adjust if necessary.
     UMA_HISTOGRAM_CUSTOM_TIMES("TabManager.Discarding.DiscardToReloadTime",
                                delta, base::TimeDelta::FromSeconds(1),
                                base::TimeDelta::FromDays(1), 100);
-    tab_data_.last_reload_time_ = NowTicks();
+
+    if (tab_data_.last_inactive_time_ != base::TimeTicks::UnixEpoch()) {
+      delta = tab_data_.last_reload_time_ - tab_data_.last_inactive_time_;
+      UMA_HISTOGRAM_CUSTOM_TIMES("TabManager.Discarding.InactiveToReloadTime",
+                                 delta, base::TimeDelta::FromSeconds(1),
+                                 base::TimeDelta::FromDays(1), 100);
+    }
+
   } else if (!tab_data_.is_discarded_ && state) {
     static int discard_count = 0;
     UMA_HISTOGRAM_CUSTOM_COUNTS("TabManager.Discarding.DiscardCount",
diff --git a/chrome/browser/memory/tab_manager_web_contents_data_unittest.cc b/chrome/browser/memory/tab_manager_web_contents_data_unittest.cc
index 69f5474..0aa9e05c 100644
--- a/chrome/browser/memory/tab_manager_web_contents_data_unittest.cc
+++ b/chrome/browser/memory/tab_manager_web_contents_data_unittest.cc
@@ -184,4 +184,24 @@
   histograms.ExpectBucketCount(kHistogramName, 13000, 1);
 }
 
+TEST_F(TabManagerWebContentsDataTest, HistogramsInactiveToReloadTime) {
+  const char kHistogramName[] = "TabManager.Discarding.InactiveToReloadTime";
+
+  base::HistogramTester histograms;
+
+  EXPECT_TRUE(histograms.GetTotalCountsForPrefix(kHistogramName).empty());
+
+  tab_data()->SetLastInactiveTime(test_clock().NowTicks());
+  test_clock().Advance(base::TimeDelta::FromSeconds(5));
+  tab_data()->SetDiscardState(true);
+  tab_data()->IncrementDiscardCount();
+  test_clock().Advance(base::TimeDelta::FromSeconds(7));
+  tab_data()->SetDiscardState(false);
+
+  EXPECT_EQ(1,
+            histograms.GetTotalCountsForPrefix(kHistogramName).begin()->second);
+
+  histograms.ExpectBucketCount(kHistogramName, 12000, 1);
+}
+
 }  // namespace memory
diff --git a/chrome/browser/password_manager/password_manager_test_base.cc b/chrome/browser/password_manager/password_manager_test_base.cc
index 2ad437a6..0a875de 100644
--- a/chrome/browser/password_manager/password_manager_test_base.cc
+++ b/chrome/browser/password_manager/password_manager_test_base.cc
@@ -191,7 +191,7 @@
   // PasswordStore has not completed.
   PasswordStoreFactory::GetInstance()->SetTestingFactory(
       browser()->profile(),
-      password_manager::BuildPasswordStoreService<
+      password_manager::BuildPasswordStore<
           content::BrowserContext, password_manager::TestPasswordStore>);
   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
   ASSERT_FALSE(base::CommandLine::ForCurrentProcess()->HasSwitch(
diff --git a/chrome/browser/password_manager/password_store_factory.cc b/chrome/browser/password_manager/password_store_factory.cc
index 72da4bf..2048d88 100644
--- a/chrome/browser/password_manager/password_store_factory.cc
+++ b/chrome/browser/password_manager/password_store_factory.cc
@@ -24,7 +24,6 @@
 #include "components/password_manager/core/browser/password_store.h"
 #include "components/password_manager/core/browser/password_store_default.h"
 #include "components/password_manager/core/browser/password_store_factory_util.h"
-#include "components/password_manager/core/browser/password_store_service.h"
 #include "components/password_manager/core/common/password_manager_pref_names.h"
 #include "components/pref_registry/pref_registry_syncable.h"
 #include "content/public/browser/browser_thread.h"
@@ -66,12 +65,14 @@
 scoped_refptr<PasswordStore> PasswordStoreFactory::GetForProfile(
     Profile* profile,
     ServiceAccessType access_type) {
-  password_manager::PasswordStoreService* service =
-      static_cast<password_manager::PasswordStoreService*>(
-          GetInstance()->GetServiceForBrowserContext(profile, true));
-
-  return password_manager::GetPasswordStoreFromService(
-      service, access_type, profile->IsOffTheRecord());
+  // |profile| gets always redirected to a non-Incognito profile below, so
+  // Incognito & IMPLICIT_ACCESS means that incognito browsing session would
+  // result in traces in the normal profile without the user knowing it.
+  if (access_type == ServiceAccessType::IMPLICIT_ACCESS &&
+      profile->IsOffTheRecord())
+    return nullptr;
+  return make_scoped_refptr(static_cast<password_manager::PasswordStore*>(
+      GetInstance()->GetServiceForBrowserContext(profile, true).get()));
 }
 
 // static
@@ -108,9 +109,9 @@
 }
 
 PasswordStoreFactory::PasswordStoreFactory()
-    : BrowserContextKeyedServiceFactory(
-        "PasswordStore",
-        BrowserContextDependencyManager::GetInstance()) {
+    : RefcountedBrowserContextKeyedServiceFactory(
+          "PasswordStore",
+          BrowserContextDependencyManager::GetInstance()) {
   DependsOn(WebDataServiceFactory::GetInstance());
 }
 
@@ -138,7 +139,8 @@
 }
 #endif
 
-KeyedService* PasswordStoreFactory::BuildServiceInstanceFor(
+scoped_refptr<RefcountedKeyedService>
+PasswordStoreFactory::BuildServiceInstanceFor(
     content::BrowserContext* context) const {
 #if defined(OS_WIN)
   password_manager_util_win::DelayReportOsPassword();
@@ -256,10 +258,15 @@
 #else
   NOTIMPLEMENTED();
 #endif
-  return password_manager::BuildServiceInstanceFromStore(
-             ps,
-             sync_start_util::GetFlareForSyncableService(profile->GetPath()))
-      .release();
+  DCHECK(ps);
+  if (!ps->Init(
+          sync_start_util::GetFlareForSyncableService(profile->GetPath()))) {
+    // TODO(crbug.com/479725): Remove the LOG once this error is visible in the
+    // UI.
+    LOG(WARNING) << "Could not initialize password store.";
+    return nullptr;
+  }
+  return ps;
 }
 
 void PasswordStoreFactory::RegisterProfilePrefs(
diff --git a/chrome/browser/password_manager/password_store_factory.h b/chrome/browser/password_manager/password_store_factory.h
index 23037f6d..07c0246 100644
--- a/chrome/browser/password_manager/password_store_factory.h
+++ b/chrome/browser/password_manager/password_store_factory.h
@@ -9,7 +9,7 @@
 
 #include "base/basictypes.h"
 #include "base/memory/singleton.h"
-#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
+#include "components/keyed_service/content/refcounted_browser_context_keyed_service_factory.h"
 #include "components/keyed_service/core/service_access_type.h"
 
 #if defined(USE_X11)
@@ -32,7 +32,8 @@
 
 // Singleton that owns all PasswordStores and associates them with
 // Profiles.
-class PasswordStoreFactory : public BrowserContextKeyedServiceFactory {
+class PasswordStoreFactory
+    : public RefcountedBrowserContextKeyedServiceFactory {
  public:
   static scoped_refptr<password_manager::PasswordStore> GetForProfile(
       Profile* profile,
@@ -58,8 +59,8 @@
   LocalProfileId GetLocalProfileId(PrefService* prefs) const;
 #endif
 
-  // BrowserContextKeyedServiceFactory:
-  KeyedService* BuildServiceInstanceFor(
+  // RefcountedBrowserContextKeyedServiceFactory:
+  scoped_refptr<RefcountedKeyedService> BuildServiceInstanceFor(
       content::BrowserContext* context) const override;
   void RegisterProfilePrefs(
       user_prefs::PrefRegistrySyncable* registry) override;
diff --git a/chrome/browser/password_manager/password_store_mac_unittest.cc b/chrome/browser/password_manager/password_store_mac_unittest.cc
index fb73ec0..996adef 100644
--- a/chrome/browser/password_manager/password_store_mac_unittest.cc
+++ b/chrome/browser/password_manager/password_store_mac_unittest.cc
@@ -1231,7 +1231,7 @@
     if (!store_)
       return;
 
-    store_->Shutdown();
+    store_->ShutdownOnUIThread();
     store_ = nullptr;
   }
 
diff --git a/chrome/browser/password_manager/password_store_proxy_mac.cc b/chrome/browser/password_manager/password_store_proxy_mac.cc
index ecbf1a6..34e6079 100644
--- a/chrome/browser/password_manager/password_store_proxy_mac.cc
+++ b/chrome/browser/password_manager/password_store_proxy_mac.cc
@@ -56,9 +56,9 @@
                  static_cast<MigrationStatus>(migration_status_.GetValue())));
 }
 
-void PasswordStoreProxyMac::Shutdown() {
+void PasswordStoreProxyMac::ShutdownOnUIThread() {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  PasswordStore::Shutdown();
+  PasswordStore::ShutdownOnUIThread();
   thread_->Stop();
 
   // Execute the task which are still pending.
@@ -71,7 +71,7 @@
   // another. GetBackend() returns the correct result.
   // The backend doesn't need the background thread as PasswordStore::Init() and
   // other public methods were never called on it.
-  GetBackend()->Shutdown();
+  GetBackend()->ShutdownOnUIThread();
 }
 
 scoped_refptr<base::SingleThreadTaskRunner>
@@ -106,8 +106,8 @@
         status = MigrationStatus::MIGRATED;
         // Switch from |password_store_mac_| to |password_store_simple_|.
         password_store_mac_->set_login_metadata_db(nullptr);
-        pending_ui_tasks_.push_back(
-            base::Bind(&PasswordStoreMac::Shutdown, password_store_mac_));
+        pending_ui_tasks_.push_back(base::Bind(
+            &PasswordStoreMac::ShutdownOnUIThread, password_store_mac_));
         password_store_mac_ = nullptr;
         DCHECK(!password_store_simple_);
         password_store_simple_ = new SimplePasswordStoreMac(
diff --git a/chrome/browser/password_manager/password_store_proxy_mac.h b/chrome/browser/password_manager/password_store_proxy_mac.h
index 10e08eb..c2b57998 100644
--- a/chrome/browser/password_manager/password_store_proxy_mac.h
+++ b/chrome/browser/password_manager/password_store_proxy_mac.h
@@ -38,7 +38,7 @@
       PrefService* prefs);
 
   bool Init(const syncer::SyncableService::StartSyncFlare& flare) override;
-  void Shutdown() override;
+  void ShutdownOnUIThread() override;
   scoped_refptr<base::SingleThreadTaskRunner> GetBackgroundTaskRunner()
       override;
 
diff --git a/chrome/browser/password_manager/password_store_proxy_mac_unittest.cc b/chrome/browser/password_manager/password_store_proxy_mac_unittest.cc
index cab284ce..204c9c7 100644
--- a/chrome/browser/password_manager/password_store_proxy_mac_unittest.cc
+++ b/chrome/browser/password_manager/password_store_proxy_mac_unittest.cc
@@ -163,7 +163,7 @@
 void PasswordStoreProxyMacTest::ClosePasswordStore() {
   if (!store_)
     return;
-  store_->Shutdown();
+  store_->ShutdownOnUIThread();
   EXPECT_FALSE(store_->GetBackgroundTaskRunner());
   store_ = nullptr;
 }
@@ -257,9 +257,9 @@
 // ----------- Tests -------------
 
 TEST_P(PasswordStoreProxyMacTest, StartAndStop) {
-  // PasswordStore::Shutdown() immediately follows PasswordStore::Init(). The
-  // message loop isn't running in between. Anyway, PasswordStore should end up
-  // in the right state.
+  // PasswordStore::ShutdownOnUIThread() immediately follows
+  // PasswordStore::Init(). The message loop isn't running in between. Anyway,
+  // PasswordStore should end up in the right state.
   ClosePasswordStore();
 
   int status = testing_prefs_.GetInteger(
diff --git a/chrome/browser/password_manager/password_store_win.cc b/chrome/browser/password_manager/password_store_win.cc
index fdb887d..db9076f 100644
--- a/chrome/browser/password_manager/password_store_win.cc
+++ b/chrome/browser/password_manager/password_store_win.cc
@@ -68,7 +68,7 @@
   scoped_refptr<PasswordWebDataService> web_data_service_;
 
   // This creates a cycle between us and PasswordStore. The cycle is broken
-  // from PasswordStoreWin::Shutdown, which deletes us.
+  // from PasswordStoreWin::ShutdownOnUIThread, which deletes us.
   scoped_refptr<PasswordStoreWin> password_store_;
 
   PendingRequestMap pending_requests_;
@@ -186,11 +186,11 @@
   db_handler_.reset();
 }
 
-void PasswordStoreWin::Shutdown() {
+void PasswordStoreWin::ShutdownOnUIThread() {
   BrowserThread::PostTask(
       BrowserThread::DB, FROM_HERE,
       base::Bind(&PasswordStoreWin::ShutdownOnDBThread, this));
-  PasswordStoreDefault::Shutdown();
+  PasswordStoreDefault::ShutdownOnUIThread();
 }
 
 void PasswordStoreWin::GetLoginsImpl(const PasswordForm& form,
diff --git a/chrome/browser/password_manager/password_store_win.h b/chrome/browser/password_manager/password_store_win.h
index 3501b2e..6287177 100644
--- a/chrome/browser/password_manager/password_store_win.h
+++ b/chrome/browser/password_manager/password_store_win.h
@@ -32,14 +32,14 @@
       const scoped_refptr<PasswordWebDataService>& web_data_service);
 
   // PasswordStore:
-  void Shutdown() override;
+  void ShutdownOnUIThread() override;
 
  private:
   class DBHandler;
 
   ~PasswordStoreWin() override;
 
-  // Invoked from Shutdown, but run on the DB thread.
+  // Invoked from ShutdownOnUIThread, but run on the DB thread.
   void ShutdownOnDBThread();
 
   // password_manager::PasswordStore:
diff --git a/chrome/browser/password_manager/password_store_win_unittest.cc b/chrome/browser/password_manager/password_store_win_unittest.cc
index 4f82876..16208a7 100644
--- a/chrome/browser/password_manager/password_store_win_unittest.cc
+++ b/chrome/browser/password_manager/password_store_win_unittest.cc
@@ -137,7 +137,7 @@
 
   void TearDown() override {
     if (store_.get())
-      store_->Shutdown();
+      store_->ShutdownOnUIThread();
     wds_->ShutdownOnUIThread();
     wdbs_->ShutdownDatabase();
     wds_ = nullptr;
@@ -285,7 +285,7 @@
   store_->GetLogins(*form, PasswordStore::DISALLOW_PROMPT, &consumer);
 
   // Release the PSW and the WDS before the query can return.
-  store_->Shutdown();
+  store_->ShutdownOnUIThread();
   store_ = nullptr;
   wds_ = nullptr;
 
diff --git a/chrome/browser/password_manager/password_store_x_unittest.cc b/chrome/browser/password_manager/password_store_x_unittest.cc
index 9567d82b..2c2a16c 100644
--- a/chrome/browser/password_manager/password_store_x_unittest.cc
+++ b/chrome/browser/password_manager/password_store_x_unittest.cc
@@ -375,7 +375,7 @@
 
   store->RemoveObserver(&observer);
 
-  store->Shutdown();
+  store->ShutdownOnUIThread();
 }
 
 TEST_P(PasswordStoreXTest, NativeMigration) {
@@ -478,7 +478,7 @@
     EXPECT_EQ(db_file_start_info.size, db_file_end_info.size);
   }
 
-  store->Shutdown();
+  store->ShutdownOnUIThread();
 }
 
 INSTANTIATE_TEST_CASE_P(NoBackend,
diff --git a/chrome/browser/password_manager/simple_password_store_mac_unittest.cc b/chrome/browser/password_manager/simple_password_store_mac_unittest.cc
index 4e82e06..26f459b 100644
--- a/chrome/browser/password_manager/simple_password_store_mac_unittest.cc
+++ b/chrome/browser/password_manager/simple_password_store_mac_unittest.cc
@@ -61,7 +61,7 @@
   }
 
   void TearDown() override {
-    store_->Shutdown();
+    store_->ShutdownOnUIThread();
     EXPECT_TRUE(store_->GetBackgroundTaskRunner());
     store_ = nullptr;
   }
diff --git a/chrome/browser/policy/policy_browsertest.cc b/chrome/browser/policy/policy_browsertest.cc
index db32c9f..b5220e0 100644
--- a/chrome/browser/policy/policy_browsertest.cc
+++ b/chrome/browser/policy/policy_browsertest.cc
@@ -2915,9 +2915,9 @@
   Mock::VerifyAndClearExpectations(&observer);
 }
 
-// Disabled, see http://crbug.com/315308.
+// Disabled, see http://crbug.com/554728.
 IN_PROC_BROWSER_TEST_F(PolicyTest,
-                       DISABLED_PRE_WaitForInitialUserActivityUsatisfied) {
+                       DISABLED_PRE_WaitForInitialUserActivityUnsatisfied) {
   // Indicate that the session started 2 hours ago and no user activity has
   // occurred yet.
   g_browser_process->local_state()->SetInt64(
@@ -2926,9 +2926,9 @@
           .ToInternalValue());
 }
 
-// Disabled, see http://crbug.com/315308.
+// Disabled, see http://crbug.com/554728.
 IN_PROC_BROWSER_TEST_F(PolicyTest,
-                       DISABLED_WaitForInitialUserActivityUsatisfied) {
+                       DISABLED_WaitForInitialUserActivityUnsatisfied) {
   content::MockNotificationObserver observer;
   content::NotificationRegistrar registrar;
   registrar.Add(&observer,
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc
index 32950be7..90a75997 100644
--- a/chrome/browser/prefs/browser_prefs.cc
+++ b/chrome/browser/prefs/browser_prefs.cc
@@ -141,8 +141,8 @@
 #include "chrome/browser/android/bookmarks/partner_bookmarks_shim.h"
 #include "chrome/browser/android/most_visited_sites.h"
 #include "chrome/browser/android/new_tab_page_prefs.h"
+#include "chrome/browser/android/popular_sites.h"
 #else
-#include "chrome/browser/profile_resetter/automatic_profile_resetter_factory.h"
 #include "chrome/browser/ui/startup/startup_browser_creator.h"
 #include "chrome/browser/upgrade_detector.h"
 #endif
@@ -289,7 +289,6 @@
 #endif  // defined(ENABLE_TASK_MANAGER)
 
 #if !defined(OS_ANDROID)
-  AutomaticProfileResetterFactory::RegisterPrefs(registry);
   BackgroundModeManager::RegisterPrefs(registry);
   ChromeTracingDelegate::RegisterPrefs(registry);
   RegisterBrowserPrefs(registry);
@@ -458,6 +457,7 @@
   MostVisitedSites::RegisterProfilePrefs(registry);
   NewTabPagePrefs::RegisterProfilePrefs(registry);
   PartnerBookmarksShim::RegisterProfilePrefs(registry);
+  PopularSites::RegisterProfilePrefs(registry);
 #else
   AppShortcutManager::RegisterProfilePrefs(registry);
   DeviceIDFetcher::RegisterProfilePrefs(registry);
diff --git a/chrome/browser/prefs/chrome_pref_service_factory.cc b/chrome/browser/prefs/chrome_pref_service_factory.cc
index fc2dcc8..4b313f43 100644
--- a/chrome/browser/prefs/chrome_pref_service_factory.cc
+++ b/chrome/browser/prefs/chrome_pref_service_factory.cc
@@ -166,12 +166,6 @@
     PrefHashFilter::TRACKING_STRATEGY_ATOMIC,
     PrefHashFilter::VALUE_IMPERSONAL
   },
-  {
-    13, prefs::kProfileResetPromptMementoInProfilePrefs,
-    PrefHashFilter::ENFORCE_ON_LOAD,
-    PrefHashFilter::TRACKING_STRATEGY_ATOMIC,
-    PrefHashFilter::VALUE_IMPERSONAL
-  },
 #endif
   {
     14, DefaultSearchManager::kDefaultSearchProviderDataPrefName,
diff --git a/chrome/browser/profile_resetter/automatic_profile_resetter.cc b/chrome/browser/profile_resetter/automatic_profile_resetter.cc
deleted file mode 100644
index 9386b27..0000000
--- a/chrome/browser/profile_resetter/automatic_profile_resetter.cc
+++ /dev/null
@@ -1,764 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/profile_resetter/automatic_profile_resetter.h"
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/logging.h"
-#include "base/memory/ref_counted.h"
-#include "base/metrics/field_trial.h"
-#include "base/metrics/histogram.h"
-#include "base/metrics/sparse_histogram.h"
-#include "base/prefs/pref_service.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_util.h"
-#include "base/task_runner.h"
-#include "base/task_runner_util.h"
-#include "base/threading/sequenced_worker_pool.h"
-#include "base/time/time.h"
-#include "base/timer/elapsed_timer.h"
-#include "base/values.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/profile_resetter/automatic_profile_resetter_delegate.h"
-#include "chrome/browser/profile_resetter/jtl_interpreter.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/search_engines/template_url_service_factory.h"
-#include "components/search_engines/template_url_service.h"
-#include "components/variations/variations_associated_data.h"
-#include "content/public/browser/browser_thread.h"
-#include "grit/browser_resources.h"
-#include "ui/base/resource/resource_bundle.h"
-
-
-// Helpers -------------------------------------------------------------------
-
-namespace {
-
-// Name constants for the field trial behind which we enable this feature.
-const char kAutomaticProfileResetStudyName[] = "AutomaticProfileReset";
-const char kAutomaticProfileResetStudyDryRunGroupName[] = "DryRun";
-const char kAutomaticProfileResetStudyEnabledGroupName[] = "Enabled";
-#if defined(GOOGLE_CHROME_BUILD)
-const char kAutomaticProfileResetStudyProgramParameterName[] = "program";
-const char kAutomaticProfileResetStudyHashSeedParameterName[] = "hash_seed";
-#endif
-
-// How long to wait after start-up before unleashing the evaluation flow.
-const int64 kEvaluationFlowDelayInSeconds = 55;
-
-// Keys used in the input dictionary of the program.
-const char kDefaultSearchProviderKey[] = "default_search_provider";
-const char kDefaultSearchProviderIsUserControlledKey[] =
-    "default_search_provider_iuc";
-const char kLoadedModuleDigestsKey[] = "loaded_modules";
-const char kLocalStateKey[] = "local_state";
-const char kLocalStateIsUserControlledKey[] = "local_state_iuc";
-const char kSearchProvidersKey[] = "search_providers";
-const char kUserPreferencesKey[] = "preferences";
-const char kUserPreferencesIsUserControlledKey[] = "preferences_iuc";
-
-// Keys used in the output dictionary of the program.
-const char kCombinedStatusMaskKeyPrefix[] = "combined_status_mask_bit";
-const char kHadPromptedAlreadyKey[] = "had_prompted_already";
-const char kShouldPromptKey[] = "should_prompt";
-const char kSatisfiedCriteriaMaskKeyPrefix[] = "satisfied_criteria_mask_bit";
-
-// Keys used in both the input and output dictionary of the program.
-const char kMementoValueInFileKey[] = "memento_value_in_file";
-const char kMementoValueInLocalStateKey[] = "memento_value_in_local_state";
-const char kMementoValueInPrefsKey[] = "memento_value_in_prefs";
-
-// Number of bits, and maximum value (exclusive) for the mask whose bits
-// indicate which of reset criteria were satisfied.
-const size_t kSatisfiedCriteriaMaskNumberOfBits = 5u;
-const uint32 kSatisfiedCriteriaMaskMaximumValue =
-    (1u << kSatisfiedCriteriaMaskNumberOfBits);
-
-// Number of bits, and maximum value (exclusive) for the mask whose bits
-// indicate if any of reset criteria were satisfied, and which of the mementos
-// were already present.
-const size_t kCombinedStatusMaskNumberOfBits = 4u;
-const uint32 kCombinedStatusMaskMaximumValue =
-    (1u << kCombinedStatusMaskNumberOfBits);
-
-// Returns whether or not a dry-run shall be performed.
-bool ShouldPerformDryRun() {
-  return base::StartsWith(
-      base::FieldTrialList::FindFullName(kAutomaticProfileResetStudyName),
-      kAutomaticProfileResetStudyDryRunGroupName, base::CompareCase::SENSITIVE);
-}
-
-// Returns whether or not a live-run shall be performed.
-bool ShouldPerformLiveRun() {
-  return base::StartsWith(
-      base::FieldTrialList::FindFullName(kAutomaticProfileResetStudyName),
-      kAutomaticProfileResetStudyEnabledGroupName,
-      base::CompareCase::SENSITIVE);
-}
-
-// If the currently active experiment group prescribes a |program| and
-// |hash_seed| to use instead of the baked-in ones, retrieves those and returns
-// true. Otherwise, returns false.
-bool GetProgramAndHashSeedOverridesFromExperiment(std::string* program,
-                                                  std::string* hash_seed) {
-  DCHECK(program);
-  DCHECK(hash_seed);
-#if defined(GOOGLE_CHROME_BUILD)
-  std::map<std::string, std::string> params;
-  variations::GetVariationParams(kAutomaticProfileResetStudyName, &params);
-  if (params.count(kAutomaticProfileResetStudyProgramParameterName) &&
-      params.count(kAutomaticProfileResetStudyHashSeedParameterName)) {
-    program->swap(params[kAutomaticProfileResetStudyProgramParameterName]);
-    hash_seed->swap(params[kAutomaticProfileResetStudyHashSeedParameterName]);
-    return true;
-  }
-#endif
-  return false;
-}
-
-// Takes |pref_name_to_value_map|, which shall be a deep-copy of all preferences
-// in |source| without path expansion; and (1.) creates a sub-tree from it named
-// |value_tree_key| in |target_dictionary| with path expansion, and (2.) also
-// creates an isomorphic sub-tree under the key |is_user_controlled_tree_key|
-// that contains only Boolean values indicating whether or not the corresponding
-// preference is coming from the 'user' PrefStore.
-void BuildSubTreesFromPreferences(
-    scoped_ptr<base::DictionaryValue> pref_name_to_value_map,
-    const PrefService* source,
-    const char* value_tree_key,
-    const char* is_user_controlled_tree_key,
-    base::DictionaryValue* target_dictionary) {
-  std::vector<std::string> pref_names;
-  pref_names.reserve(pref_name_to_value_map->size());
-  for (base::DictionaryValue::Iterator it(*pref_name_to_value_map);
-       !it.IsAtEnd(); it.Advance())
-    pref_names.push_back(it.key());
-
-  base::DictionaryValue* value_tree = new base::DictionaryValue;
-  base::DictionaryValue* is_user_controlled_tree = new base::DictionaryValue;
-  for (std::vector<std::string>::const_iterator it = pref_names.begin();
-       it != pref_names.end(); ++it) {
-    scoped_ptr<base::Value> pref_value_owned;
-    if (pref_name_to_value_map->RemoveWithoutPathExpansion(*it,
-                                                           &pref_value_owned)) {
-      value_tree->Set(*it, pref_value_owned.release());
-      const PrefService::Preference* pref = source->FindPreference(it->c_str());
-      is_user_controlled_tree->Set(
-          *it, new base::FundamentalValue(pref->IsUserControlled()));
-    }
-  }
-  target_dictionary->Set(value_tree_key, value_tree);
-  target_dictionary->Set(is_user_controlled_tree_key, is_user_controlled_tree);
-}
-
-}  // namespace
-
-
-// AutomaticProfileResetter::InputBuilder ------------------------------------
-
-// Collects all the information that is required by the evaluator program to
-// assess whether or not the conditions for showing the reset prompt are met.
-//
-// This necessitates a lot of work that has to be performed on the UI thread,
-// such as: accessing the Preferences, Local State, and TemplateURLService.
-// In order to keep the browser responsive, the UI thread shall not be blocked
-// for long consecutive periods of time. Unfortunately, we cannot reduce the
-// total amount of work. Instead, what this class does is to split the work into
-// shorter tasks that are posted one-at-a-time to the UI thread in a serial
-// fashion, so as to give a chance to run other tasks that have accumulated in
-// the meantime.
-class AutomaticProfileResetter::InputBuilder
-    : public base::SupportsWeakPtr<InputBuilder> {
- public:
-  typedef base::Callback<void(scoped_ptr<base::DictionaryValue>)>
-      ProgramInputCallback;
-
-  // The dependencies must have been initialized through |delegate|, i.e. the
-  // RequestCallback[...] methods must have already fired before calling this.
-  InputBuilder(Profile* profile, AutomaticProfileResetterDelegate* delegate)
-      : profile_(profile),
-        delegate_(delegate),
-        memento_in_prefs_(profile_),
-        memento_in_local_state_(profile_),
-        memento_in_file_(profile_) {}
-  ~InputBuilder() {}
-
-  // Assembles the data required by the evaluator program into a dictionary
-  // format, and posts it back to the UI thread with |callback| once ready. In
-  // order not to block the UI thread for long consecutive periods of time, the
-  // work is divided into smaller tasks, see class comment above for details.
-  // It is safe to destroy |this| immediately from within the |callback|.
-  void BuildEvaluatorProgramInput(const ProgramInputCallback& callback) {
-    DCHECK(!data_);
-    DCHECK(!callback.is_null());
-    data_.reset(new base::DictionaryValue);
-    callback_ = callback;
-
-    AddAsyncTask(base::Bind(&InputBuilder::IncludeMementoValues, AsWeakPtr()));
-    AddTask(base::Bind(&InputBuilder::IncludeUserPreferences, AsWeakPtr()));
-    AddTask(base::Bind(&InputBuilder::IncludeLocalState, AsWeakPtr()));
-    AddTask(base::Bind(&InputBuilder::IncludeSearchEngines, AsWeakPtr()));
-    AddTask(base::Bind(&InputBuilder::IncludeLoadedModules, AsWeakPtr()));
-
-    // Each task will post the next one. Just trigger the chain reaction.
-    PostNextTask();
-  }
-
- private:
-  // Asynchronous task that includes memento values (or empty strings in case
-  // mementos are not there).
-  void IncludeMementoValues() {
-    data_->SetString(kMementoValueInPrefsKey, memento_in_prefs_.ReadValue());
-    data_->SetString(kMementoValueInLocalStateKey,
-                     memento_in_local_state_.ReadValue());
-    memento_in_file_.ReadValue(base::Bind(
-        &InputBuilder::IncludeFileBasedMementoCallback, AsWeakPtr()));
-  }
-
-  // Called back by |memento_in_file_| once the |memento_value| has been read.
-  void IncludeFileBasedMementoCallback(const std::string& memento_value) {
-    DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-    data_->SetString(kMementoValueInFileKey, memento_value);
-    // As an asynchronous task, we need to take care of posting the next task.
-    PostNextTask();
-  }
-
-  // Task that includes all user (i.e. profile-specific) preferences, along with
-  // information about whether the value is coming from the 'user' PrefStore.
-  // This is the most expensive operation, so it is itself split into two parts.
-  void IncludeUserPreferences() {
-    PrefService* prefs = profile_->GetPrefs();
-    DCHECK(prefs);
-    scoped_ptr<base::DictionaryValue> pref_name_to_value_map(
-        prefs->GetPreferenceValuesWithoutPathExpansion());
-    AddTask(base::Bind(&InputBuilder::IncludeUserPreferencesPartTwo,
-                       AsWeakPtr(),
-                       base::Passed(&pref_name_to_value_map)));
-  }
-
-  // Second part to above.
-  void IncludeUserPreferencesPartTwo(
-      scoped_ptr<base::DictionaryValue> pref_name_to_value_map) {
-    PrefService* prefs = profile_->GetPrefs();
-    DCHECK(prefs);
-    BuildSubTreesFromPreferences(
-        pref_name_to_value_map.Pass(),
-        prefs,
-        kUserPreferencesKey,
-        kUserPreferencesIsUserControlledKey,
-        data_.get());
-  }
-
-  // Task that includes all local state (i.e. shared) preferences, along with
-  // information about whether the value is coming from the 'user' PrefStore.
-  void IncludeLocalState() {
-    PrefService* local_state = g_browser_process->local_state();
-    DCHECK(local_state);
-    scoped_ptr<base::DictionaryValue> pref_name_to_value_map(
-        local_state->GetPreferenceValuesWithoutPathExpansion());
-    BuildSubTreesFromPreferences(
-        pref_name_to_value_map.Pass(),
-        local_state,
-        kLocalStateKey,
-        kLocalStateIsUserControlledKey,
-        data_.get());
-  }
-
-  // Task that includes all information related to search engines.
-  void IncludeSearchEngines() {
-    scoped_ptr<base::DictionaryValue> default_search_provider_details(
-        delegate_->GetDefaultSearchProviderDetails());
-    data_->Set(kDefaultSearchProviderKey,
-               default_search_provider_details.release());
-
-    scoped_ptr<base::ListValue> search_providers_details(
-        delegate_->GetPrepopulatedSearchProvidersDetails());
-    data_->Set(kSearchProvidersKey, search_providers_details.release());
-
-    data_->SetBoolean(kDefaultSearchProviderIsUserControlledKey,
-                      !delegate_->IsDefaultSearchProviderManaged());
-  }
-
-  // Task that includes information about loaded modules.
-  void IncludeLoadedModules() {
-    scoped_ptr<base::ListValue> loaded_module_digests(
-        delegate_->GetLoadedModuleNameDigests());
-    data_->Set(kLoadedModuleDigestsKey, loaded_module_digests.release());
-  }
-
-  // -------------------------------------------------------------------------
-
-  // Adds a |task| that can do as much asynchronous processing as it wants, but
-  // will need to finally call PostNextTask() on the UI thread when done.
-  void AddAsyncTask(const base::Closure& task) {
-    task_queue_.push(task);
-  }
-
-  // Convenience wrapper for synchronous tasks.
-  void SynchronousTaskWrapper(const base::Closure& task) {
-    base::ElapsedTimer timer;
-    task.Run();
-    UMA_HISTOGRAM_CUSTOM_TIMES(
-        "AutomaticProfileReset.InputBuilder.TaskDuration",
-        timer.Elapsed(),
-        base::TimeDelta::FromMilliseconds(1),
-        base::TimeDelta::FromSeconds(2),
-        50);
-    PostNextTask();
-  }
-
-  // Adds a task that needs to finish synchronously. In exchange, PostNextTask()
-  // is called automatically when the |task| returns, and execution time is
-  // measured.
-  void AddTask(const base::Closure& task) {
-    task_queue_.push(
-        base::Bind(&InputBuilder::SynchronousTaskWrapper, AsWeakPtr(), task));
-  }
-
-  // Posts the next task from the |task_queue_|, unless it is exhausted, in
-  // which case it posts |callback_| to return with the results.
-  void PostNextTask() {
-    base::Closure next_task;
-    if (task_queue_.empty()) {
-      next_task = base::Bind(callback_, base::Passed(&data_));
-    } else {
-      next_task = task_queue_.front();
-      task_queue_.pop();
-    }
-    content::BrowserThread::PostTask(
-        content::BrowserThread::UI, FROM_HERE, next_task);
-  }
-
-  Profile* profile_;
-  AutomaticProfileResetterDelegate* delegate_;
-  ProgramInputCallback callback_;
-
-  PreferenceHostedPromptMemento memento_in_prefs_;
-  LocalStateHostedPromptMemento memento_in_local_state_;
-  FileHostedPromptMemento memento_in_file_;
-
-  scoped_ptr<base::DictionaryValue> data_;
-  std::queue<base::Closure> task_queue_;
-
-  DISALLOW_COPY_AND_ASSIGN(InputBuilder);
-};
-
-
-// AutomaticProfileResetter::EvaluationResults -------------------------------
-
-// Encapsulates the output values extracted from the evaluator program.
-struct AutomaticProfileResetter::EvaluationResults {
-  EvaluationResults()
-      : should_prompt(false),
-        had_prompted_already(false),
-        satisfied_criteria_mask(0),
-        combined_status_mask(0) {}
-
-  std::string memento_value_in_prefs;
-  std::string memento_value_in_local_state;
-  std::string memento_value_in_file;
-
-  bool should_prompt;
-  bool had_prompted_already;
-  uint32 satisfied_criteria_mask;
-  uint32 combined_status_mask;
-};
-
-
-// AutomaticProfileResetter --------------------------------------------------
-
-AutomaticProfileResetter::AutomaticProfileResetter(Profile* profile)
-    : profile_(profile),
-      state_(STATE_UNINITIALIZED),
-      enumeration_of_loaded_modules_ready_(false),
-      template_url_service_ready_(false),
-      has_already_dismissed_prompt_(false),
-      should_show_reset_banner_(false),
-      weak_ptr_factory_(this) {
-  DCHECK(profile_);
-}
-
-AutomaticProfileResetter::~AutomaticProfileResetter() {}
-
-void AutomaticProfileResetter::Initialize() {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  DCHECK_EQ(state_, STATE_UNINITIALIZED);
-
-  if (!ShouldPerformDryRun() && !ShouldPerformLiveRun()) {
-    state_ = STATE_DISABLED;
-    return;
-  }
-
-  if (!GetProgramAndHashSeedOverridesFromExperiment(&program_, &hash_seed_)) {
-    ui::ResourceBundle& resources(ui::ResourceBundle::GetSharedInstance());
-    if (ShouldPerformLiveRun()) {
-      program_ = resources.GetRawDataResource(
-          IDR_AUTOMATIC_PROFILE_RESET_RULES).as_string();
-      hash_seed_ = resources.GetRawDataResource(
-          IDR_AUTOMATIC_PROFILE_RESET_HASH_SEED).as_string();
-    } else {  // ShouldPerformDryRun()
-      program_ = resources.GetRawDataResource(
-          IDR_AUTOMATIC_PROFILE_RESET_RULES_DRY).as_string();
-      hash_seed_ = resources.GetRawDataResource(
-          IDR_AUTOMATIC_PROFILE_RESET_HASH_SEED_DRY).as_string();
-    }
-  }
-
-  delegate_.reset(new AutomaticProfileResetterDelegateImpl(
-      profile_, ProfileResetter::ALL));
-  task_runner_for_waiting_ =
-      content::BrowserThread::GetMessageLoopProxyForThread(
-          content::BrowserThread::UI);
-
-  state_ = STATE_INITIALIZED;
-}
-
-void AutomaticProfileResetter::Activate() {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  DCHECK(state_ == STATE_INITIALIZED || state_ == STATE_DISABLED);
-
-  if (state_ == STATE_INITIALIZED) {
-    if (!program_.empty()) {
-      // Some steps in the flow (e.g. loaded modules, file-based memento) are
-      // IO-intensive, so defer execution until some time later.
-      task_runner_for_waiting_->PostDelayedTask(
-          FROM_HERE,
-          base::Bind(&AutomaticProfileResetter::PrepareEvaluationFlow,
-                     weak_ptr_factory_.GetWeakPtr()),
-          base::TimeDelta::FromSeconds(kEvaluationFlowDelayInSeconds));
-    } else {
-      // Terminate early if there is no program included (nor set by tests).
-      state_ = STATE_DISABLED;
-    }
-  }
-}
-
-void AutomaticProfileResetter::TriggerProfileReset(bool send_feedback) {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  DCHECK_EQ(state_, STATE_HAS_SHOWN_BUBBLE);
-
-  state_ = STATE_PERFORMING_RESET;
-  should_show_reset_banner_ = false;
-
-  ReportPromptResult(PROMPT_ACTION_RESET);
-  delegate_->TriggerProfileSettingsReset(
-      send_feedback,
-      base::Bind(&AutomaticProfileResetter::OnProfileSettingsResetCompleted,
-                 weak_ptr_factory_.GetWeakPtr()));
-}
-
-void AutomaticProfileResetter::SkipProfileReset() {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  DCHECK_EQ(state_, STATE_HAS_SHOWN_BUBBLE);
-
-  should_show_reset_banner_ = false;
-
-  ReportPromptResult(PROMPT_ACTION_NO_RESET);
-  delegate_->DismissPrompt();
-  FinishResetPromptFlow();
-}
-
-bool AutomaticProfileResetter::IsResetPromptFlowActive() const {
-  return state_ == STATE_HAS_TRIGGERED_PROMPT ||
-      state_ == STATE_HAS_SHOWN_BUBBLE;
-}
-
-bool AutomaticProfileResetter::ShouldShowResetBanner() const {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  return should_show_reset_banner_ && ShouldPerformLiveRun();
-}
-
-void AutomaticProfileResetter::NotifyDidShowResetBubble() {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  DCHECK_EQ(state_, STATE_HAS_TRIGGERED_PROMPT);
-
-  state_ = STATE_HAS_SHOWN_BUBBLE;
-
-  PersistMementos();
-  ReportPromptResult(PROMPT_SHOWN_BUBBLE);
-}
-
-void AutomaticProfileResetter::NotifyDidOpenWebUIResetDialog() {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-
-  // This notification is invoked unconditionally by the WebUI, only care about
-  // it when the prompt flow is currently active (and not yet resetting).
-  if (state_ == STATE_HAS_TRIGGERED_PROMPT ||
-      state_ == STATE_HAS_SHOWN_BUBBLE) {
-    has_already_dismissed_prompt_ = true;
-    delegate_->DismissPrompt();
-  }
-}
-
-void AutomaticProfileResetter::NotifyDidCloseWebUIResetDialog(
-    bool performed_reset) {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-
-  // This notification is invoked unconditionally by the WebUI, only care about
-  // it when the prompt flow is currently active (and not yet resetting).
-  if (state_ == STATE_HAS_TRIGGERED_PROMPT ||
-      state_ == STATE_HAS_SHOWN_BUBBLE) {
-    if (!has_already_dismissed_prompt_)
-      delegate_->DismissPrompt();
-    if (state_ == STATE_HAS_TRIGGERED_PROMPT) {
-      PersistMementos();
-      ReportPromptResult(performed_reset ?
-          PROMPT_NOT_SHOWN_BUBBLE_BUT_HAD_WEBUI_RESET :
-          PROMPT_NOT_SHOWN_BUBBLE_BUT_HAD_WEBUI_NO_RESET);
-    } else {  // if (state_ == STATE_HAS_SHOWN_PROMPT)
-      ReportPromptResult(performed_reset ?
-          PROMPT_FOLLOWED_BY_WEBUI_RESET :
-          PROMPT_FOLLOWED_BY_WEBUI_NO_RESET);
-    }
-    FinishResetPromptFlow();
-  }
-}
-
-void AutomaticProfileResetter::NotifyDidCloseWebUIResetBanner() {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  should_show_reset_banner_ = false;
-}
-
-void AutomaticProfileResetter::SetProgramForTesting(
-    const std::string& program) {
-  program_ = program;
-}
-
-void AutomaticProfileResetter::SetHashSeedForTesting(
-    const std::string& hash_key) {
-  hash_seed_ = hash_key;
-}
-
-void AutomaticProfileResetter::SetDelegateForTesting(
-    scoped_ptr<AutomaticProfileResetterDelegate> delegate) {
-  delegate_ = delegate.Pass();
-}
-
-void AutomaticProfileResetter::SetTaskRunnerForWaitingForTesting(
-    const scoped_refptr<base::TaskRunner>& task_runner) {
-  task_runner_for_waiting_ = task_runner;
-}
-
-void AutomaticProfileResetter::Shutdown() {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-
-  // We better not do anything substantial at this point. The metrics service
-  // has already been shut down; and local state has already been commited to
-  // file (in the regular fashion) for the last time.
-
-  state_ = STATE_DISABLED;
-
-  weak_ptr_factory_.InvalidateWeakPtrs();
-  delegate_.reset();
-}
-
-void AutomaticProfileResetter::PrepareEvaluationFlow() {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  DCHECK_EQ(state_, STATE_INITIALIZED);
-
-  state_ = STATE_WAITING_ON_DEPENDENCIES;
-
-  delegate_->RequestCallbackWhenTemplateURLServiceIsLoaded(
-      base::Bind(&AutomaticProfileResetter::OnTemplateURLServiceIsLoaded,
-                 weak_ptr_factory_.GetWeakPtr()));
-  delegate_->RequestCallbackWhenLoadedModulesAreEnumerated(
-      base::Bind(&AutomaticProfileResetter::OnLoadedModulesAreEnumerated,
-                 weak_ptr_factory_.GetWeakPtr()));
-  delegate_->LoadTemplateURLServiceIfNeeded();
-  delegate_->EnumerateLoadedModulesIfNeeded();
-}
-
-void AutomaticProfileResetter::OnTemplateURLServiceIsLoaded() {
-  template_url_service_ready_ = true;
-  OnDependencyIsReady();
-}
-
-void AutomaticProfileResetter::OnLoadedModulesAreEnumerated() {
-  enumeration_of_loaded_modules_ready_ = true;
-  OnDependencyIsReady();
-}
-
-void AutomaticProfileResetter::OnDependencyIsReady() {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  DCHECK_EQ(state_, STATE_WAITING_ON_DEPENDENCIES);
-
-  if (template_url_service_ready_ && enumeration_of_loaded_modules_ready_) {
-    state_ = STATE_READY;
-    content::BrowserThread::PostTask(
-        content::BrowserThread::UI,
-        FROM_HERE,
-        base::Bind(&AutomaticProfileResetter::BeginEvaluationFlow,
-                   weak_ptr_factory_.GetWeakPtr()));
-  }
-}
-
-void AutomaticProfileResetter::BeginEvaluationFlow() {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  DCHECK_EQ(state_, STATE_READY);
-  DCHECK(!program_.empty());
-  DCHECK(!input_builder_);
-
-  state_ = STATE_EVALUATING_CONDITIONS;
-
-  input_builder_.reset(new InputBuilder(profile_, delegate_.get()));
-  input_builder_->BuildEvaluatorProgramInput(
-      base::Bind(&AutomaticProfileResetter::ContinueWithEvaluationFlow,
-                 weak_ptr_factory_.GetWeakPtr()));
-}
-
-void AutomaticProfileResetter::ContinueWithEvaluationFlow(
-    scoped_ptr<base::DictionaryValue> program_input) {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  DCHECK_EQ(state_, STATE_EVALUATING_CONDITIONS);
-
-  input_builder_.reset();
-
-  base::SequencedWorkerPool* blocking_pool =
-      content::BrowserThread::GetBlockingPool();
-  scoped_refptr<base::TaskRunner> task_runner =
-      blocking_pool->GetTaskRunnerWithShutdownBehavior(
-          base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
-
-  base::PostTaskAndReplyWithResult(
-      task_runner.get(),
-      FROM_HERE,
-      base::Bind(&EvaluateConditionsOnWorkerPoolThread,
-                 hash_seed_,
-                 program_,
-                 base::Passed(&program_input)),
-      base::Bind(&AutomaticProfileResetter::FinishEvaluationFlow,
-                 weak_ptr_factory_.GetWeakPtr()));
-}
-
-// static
-scoped_ptr<AutomaticProfileResetter::EvaluationResults>
-    AutomaticProfileResetter::EvaluateConditionsOnWorkerPoolThread(
-    const std::string& hash_seed,
-    const std::string& program,
-    scoped_ptr<base::DictionaryValue> program_input) {
-  JtlInterpreter interpreter(hash_seed, program, program_input.get());
-  interpreter.Execute();
-  UMA_HISTOGRAM_ENUMERATION("AutomaticProfileReset.InterpreterResult",
-                            interpreter.result(),
-                            JtlInterpreter::RESULT_MAX);
-  UMA_HISTOGRAM_SPARSE_SLOWLY("AutomaticProfileReset.ProgramChecksum",
-                              interpreter.CalculateProgramChecksum());
-
-  // In each case below, the respective field in result originally contains the
-  // default, so if the getter fails, we still have the correct value there.
-  scoped_ptr<EvaluationResults> results(new EvaluationResults);
-  interpreter.GetOutputBoolean(kShouldPromptKey, &results->should_prompt);
-  interpreter.GetOutputBoolean(kHadPromptedAlreadyKey,
-                               &results->had_prompted_already);
-  interpreter.GetOutputString(kMementoValueInPrefsKey,
-                              &results->memento_value_in_prefs);
-  interpreter.GetOutputString(kMementoValueInLocalStateKey,
-                              &results->memento_value_in_local_state);
-  interpreter.GetOutputString(kMementoValueInFileKey,
-                              &results->memento_value_in_file);
-  for (size_t i = 0; i < kCombinedStatusMaskNumberOfBits; ++i) {
-    bool flag = false;
-    std::string mask_i_th_bit_key =
-        kCombinedStatusMaskKeyPrefix + base::SizeTToString(i + 1);
-    if (interpreter.GetOutputBoolean(mask_i_th_bit_key, &flag) && flag)
-      results->combined_status_mask |= (1 << i);
-  }
-  for (size_t i = 0; i < kSatisfiedCriteriaMaskNumberOfBits; ++i) {
-    bool flag = false;
-    std::string mask_i_th_bit_key =
-        kSatisfiedCriteriaMaskKeyPrefix + base::SizeTToString(i + 1);
-    if (interpreter.GetOutputBoolean(mask_i_th_bit_key, &flag) && flag)
-      results->satisfied_criteria_mask |= (1 << i);
-  }
-  return results.Pass();
-}
-
-void AutomaticProfileResetter::ReportStatistics(uint32 satisfied_criteria_mask,
-                                                uint32 combined_status_mask) {
-  UMA_HISTOGRAM_ENUMERATION("AutomaticProfileReset.SatisfiedCriteriaMask",
-                            satisfied_criteria_mask,
-                            kSatisfiedCriteriaMaskMaximumValue);
-  UMA_HISTOGRAM_ENUMERATION("AutomaticProfileReset.CombinedStatusMask",
-                            combined_status_mask,
-                            kCombinedStatusMaskMaximumValue);
-}
-
-void AutomaticProfileResetter::FinishEvaluationFlow(
-    scoped_ptr<EvaluationResults> results) {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  DCHECK_EQ(state_, STATE_EVALUATING_CONDITIONS);
-
-  ReportStatistics(results->satisfied_criteria_mask,
-                   results->combined_status_mask);
-
-  if (results->should_prompt)
-    should_show_reset_banner_ = true;
-
-  if (results->should_prompt && !results->had_prompted_already) {
-    evaluation_results_ = results.Pass();
-    BeginResetPromptFlow();
-  } else {
-    state_ = STATE_DONE;
-  }
-}
-
-void AutomaticProfileResetter::BeginResetPromptFlow() {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  DCHECK_EQ(state_, STATE_EVALUATING_CONDITIONS);
-
-  state_ = STATE_HAS_TRIGGERED_PROMPT;
-
-  if (ShouldPerformLiveRun() && delegate_->TriggerPrompt()) {
-    // Start fetching the brandcoded default settings speculatively in the
-    // background, so as to reduce waiting time if the user chooses to go
-    // through with the reset.
-    delegate_->FetchBrandcodedDefaultSettingsIfNeeded();
-  } else {
-    PersistMementos();
-    ReportPromptResult(PROMPT_NOT_TRIGGERED);
-    FinishResetPromptFlow();
-  }
-}
-
-void AutomaticProfileResetter::OnProfileSettingsResetCompleted() {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  DCHECK_EQ(state_, STATE_PERFORMING_RESET);
-
-  delegate_->DismissPrompt();
-  FinishResetPromptFlow();
-}
-
-void AutomaticProfileResetter::ReportPromptResult(PromptResult result) {
-  UMA_HISTOGRAM_ENUMERATION(
-      "AutomaticProfileReset.PromptResult", result, PROMPT_RESULT_MAX);
-}
-
-void AutomaticProfileResetter::PersistMementos() {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  DCHECK(state_ == STATE_HAS_TRIGGERED_PROMPT ||
-         state_ == STATE_HAS_SHOWN_BUBBLE);
-  DCHECK(evaluation_results_);
-
-  PreferenceHostedPromptMemento memento_in_prefs(profile_);
-  LocalStateHostedPromptMemento memento_in_local_state(profile_);
-  FileHostedPromptMemento memento_in_file(profile_);
-
-  memento_in_prefs.StoreValue(evaluation_results_->memento_value_in_prefs);
-  memento_in_local_state.StoreValue(
-      evaluation_results_->memento_value_in_local_state);
-  memento_in_file.StoreValue(evaluation_results_->memento_value_in_file);
-
-  evaluation_results_.reset();
-}
-
-void AutomaticProfileResetter::FinishResetPromptFlow() {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  DCHECK(state_ == STATE_HAS_TRIGGERED_PROMPT ||
-         state_ == STATE_HAS_SHOWN_BUBBLE ||
-         state_ == STATE_PERFORMING_RESET);
-  DCHECK(!evaluation_results_);
-
-  state_ = STATE_DONE;
-}
diff --git a/chrome/browser/profile_resetter/automatic_profile_resetter.h b/chrome/browser/profile_resetter/automatic_profile_resetter.h
deleted file mode 100644
index 0e43a1b5..0000000
--- a/chrome/browser/profile_resetter/automatic_profile_resetter.h
+++ /dev/null
@@ -1,268 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_PROFILE_RESETTER_AUTOMATIC_PROFILE_RESETTER_H_
-#define CHROME_BROWSER_PROFILE_RESETTER_AUTOMATIC_PROFILE_RESETTER_H_
-
-#include <string>
-
-#include "base/basictypes.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/memory/weak_ptr.h"
-#include "base/strings/string_piece.h"
-#include "base/task_runner.h"
-#include "chrome/browser/profile_resetter/automatic_profile_resetter_mementos.h"
-#include "components/keyed_service/core/keyed_service.h"
-
-class AutomaticProfileResetterDelegate;
-class Profile;
-
-namespace base {
-class DictionaryValue;
-class ListValue;
-}
-
-// This service is responsible for evaluating whether the criteria for showing
-// the one-time profile reset prompt are satisfied, and for potentially
-// triggering the prompt. To ensure that the prompt only appears at most once
-// for any given profile, a "memento" that the prompt has appeared is written to
-// the profile on disk; see automatic_profile_resetter_mementos.h for details.
-// The service is created automatically with the Profile and is activated right
-// away by its factory. To avoid delaying start-up, however, it will only start
-// working after a short delay.
-// All methods in this class shall be called on the UI thread, except when noted
-// otherwise.
-class AutomaticProfileResetter : public KeyedService {
- public:
-  // Enumeration listing the possible outcomes of triggering the profile reset
-  // prompt.
-  enum PromptResult {
-    // The reset prompt was not triggered because only a dry-run was performed,
-    // or because it was not supported on the current platform.
-    PROMPT_NOT_TRIGGERED,
-    // The reset bubble actually got shown. In contrast to the wrench menu item
-    // that can always be shown, the bubble might be delayed or might never be
-    // shown if another bubble was shown at the time of triggering the prompt.
-    // This enumeration value is usually recorded in conjunction with another
-    // PromptResult, the absence of which indicates that the prompt was ignored.
-    PROMPT_SHOWN_BUBBLE,
-    // The user selected "Reset" or "No, thanks" (respectively) directly from
-    // within the bubble.
-    PROMPT_ACTION_RESET,
-    PROMPT_ACTION_NO_RESET,
-    // The reset bubble was shown, then dismissed without taking definitive
-    // action. Then, however, the user initiated or refrained from doing a reset
-    // (respectively) from the conventional, WebUI-based reset dialog.
-    PROMPT_FOLLOWED_BY_WEBUI_RESET,
-    PROMPT_FOLLOWED_BY_WEBUI_NO_RESET,
-    // The reset bubble was suppressed (not shown) because another bubble was
-    // already being shown at the time. Regardless, however, the user initiated
-    // or refrained from doing a reset (respectively) from the conventional,
-    // WebUI-based reset dialog.
-    PROMPT_NOT_SHOWN_BUBBLE_BUT_HAD_WEBUI_RESET,
-    PROMPT_NOT_SHOWN_BUBBLE_BUT_HAD_WEBUI_NO_RESET,
-    PROMPT_RESULT_MAX
-  };
-
-  explicit AutomaticProfileResetter(Profile* profile);
-  ~AutomaticProfileResetter() override;
-
-  // Initializes the service if it is enabled in the field trial. Otherwise,
-  // skips the initialization steps, and also permanently disables the service.
-  // Called by AutomaticProfileResetterFactory.
-  void Initialize();
-
-  // Fires up the service by unleashing the asynchronous evaluation flow, unless
-  // the service has been already disabled in Initialize() or there is no
-  // |program_| to run (in which case the service also gets disabled).
-  // Called by the AutomaticProfileResetterFactory.
-  void Activate();
-
-  // Called in case the user chooses to reset their profile settings from inside
-  // the reset bubble. Will trigger the reset, optionally |send_feedback|, and
-  // conclude the reset prompt flow.
-  void TriggerProfileReset(bool send_feedback);
-
-  // Called in case the user chooses from inside the reset bubble that they do
-  // not want to reset their profile settings. Will conclude the reset prompt
-  // flow without setting off a reset.
-  void SkipProfileReset();
-
-  // Returns whether or not the profile reset prompt flow is currently active,
-  // that is, we have triggered the prompt and are waiting for the user to take
-  // definitive action (and we are not yet performing a reset).
-  bool IsResetPromptFlowActive() const;
-
-  // Returns whether or not the profile reset banner should be shown on the
-  // WebUI-based settings page.
-  bool ShouldShowResetBanner() const;
-
-  // Called to give notice that the reset bubble has actually been shown.
-  void NotifyDidShowResetBubble();
-
-  // Called to give notice that the conventional, WebUI-based settings reset
-  // dialog has been opened. This will dismiss the menu item in the wrench menu.
-  // This should always be followed by a corresponding call to
-  // NotifyDidCloseWebUIResetDialog().
-  void NotifyDidOpenWebUIResetDialog();
-
-  // Called to give notice that the conventional, WebUI-based settings reset
-  // dialog has been closed, with |performed_reset| indicating whether or not a
-  // reset was requested. This is required so that we can record the appropriate
-  // PromptResult, dismiss the prompt, and conclude the reset prompt flow early
-  // without setting off any resets in the future.
-  void NotifyDidCloseWebUIResetDialog(bool performed_reset);
-
-  // Called to give notice that reset banner has been dismissed as a result of
-  // user action on the WebUI-based settings page itself.
-  void NotifyDidCloseWebUIResetBanner();
-
-  base::WeakPtr<AutomaticProfileResetter> AsWeakPtr() {
-    return weak_ptr_factory_.GetWeakPtr();
-  }
-
-  // Should be called before Activate().
-  void SetProgramForTesting(const std::string& program);
-
-  // Should be called before Activate().
-  void SetHashSeedForTesting(const std::string& hash_seed);
-
-  // Should be called before Activate().
-  void SetDelegateForTesting(
-      scoped_ptr<AutomaticProfileResetterDelegate> delegate);
-
-  // Should be called before Activate(). Sets the task runner to be used to post
-  // task |PrepareEvaluationFlow| in a delayed manner.
-  void SetTaskRunnerForWaitingForTesting(
-      const scoped_refptr<base::TaskRunner>& task_runner);
-
-  // KeyedService:
-  void Shutdown() override;
-
- private:
-  class InputBuilder;
-  struct EvaluationResults;
-
-  enum State {
-    STATE_UNINITIALIZED,
-    STATE_INITIALIZED,
-    STATE_DISABLED,
-    STATE_WAITING_ON_DEPENDENCIES,
-    STATE_READY,
-    STATE_EVALUATING_CONDITIONS,
-    // The reset prompt has been triggered; but the reset bubble has not yet
-    // been shown.
-    STATE_HAS_TRIGGERED_PROMPT,
-    // The reset prompt has been triggered; the reset bubble has been shown, and
-    // potentially already dismissed by the user.
-    STATE_HAS_SHOWN_BUBBLE,
-    STATE_PERFORMING_RESET,
-    STATE_DONE
-  };
-
-  // Prepares the asynchronous evaluation flow by requesting services that it
-  // depends on to make themselves ready.
-  void PrepareEvaluationFlow();
-
-  // Called back by |resetter_delegate_| when the template URL service is ready.
-  void OnTemplateURLServiceIsLoaded();
-
-  // Called back by |resetter_delegate_| when the loaded modules have been
-  // enumerated.
-  void OnLoadedModulesAreEnumerated();
-
-  // Invoked by the above two methods. Kicks off the actual evaluation flow.
-  void OnDependencyIsReady();
-
-  // Begins the asynchronous evaluation flow, which will assess whether the
-  // criteria for showing the reset prompt are met, whether we have already
-  // shown the prompt; and, in the end, will potentially trigger the prompt.
-  void BeginEvaluationFlow();
-
-  // Called by InputBuilder once it has finished assembling the |program_input|,
-  // and will continue with the evaluation flow by triggering the evaluator
-  // program on the worker thread.
-  void ContinueWithEvaluationFlow(
-      scoped_ptr<base::DictionaryValue> program_input);
-
-  // Performs the bulk of the work. Invokes the JTL interpreter to run the
-  // |program| that will evaluate whether the conditions are met for showing the
-  // reset prompt. The program will make this decision based on the state
-  // information contained in |input| in the form of key-value pairs. The
-  // program will only see hashed keys and values that are produced using
-  // |hash_seed| as a key.
-  static scoped_ptr<EvaluationResults> EvaluateConditionsOnWorkerPoolThread(
-      const std::string& hash_seed,
-      const std::string& program,
-      scoped_ptr<base::DictionaryValue> program_input);
-
-  // Reports the given metrics through UMA. Virtual, so it can be mocked out in
-  // tests to verify that the correct value are being reported.
-  virtual void ReportStatistics(uint32 satisfied_criteria_mask,
-                                uint32 combined_status_mask);
-
-  // Called back when EvaluateConditionsOnWorkerPoolThread completes executing
-  // the program with |results|. Finishes the evaluation flow, and, based on the
-  // result, potentially initiates the reset prompt flow.
-  void FinishEvaluationFlow(scoped_ptr<EvaluationResults> results);
-
-  // Begins the reset prompt flow by triggering the reset prompt, which consists
-  // of two parts: (1.) the profile reset (pop-up) bubble, and (2.) a menu item
-  // in the wrench menu (provided by a GlobalError).
-  // The flow lasts until we receive a clear indication from the user about
-  // whether or not they wish to reset their settings. This indication can come
-  // in a variety of flavors:
-  //  * taking definitive action (i.e. selecting either "Reset" or "No, thanks")
-  //    in the pop-up reset bubble itself,
-  //  * dismissing the bubble, but then selecting the wrench menu item, which
-  //    takes them to the WebUI reset dialog in chrome://settings, and then the
-  //    user can make their choice there,
-  //  * the user going to the WebUI reset dialog by themself.
-  // For the most part, the conclusion of the reset flow coincides with when the
-  // reset prompt is dismissed, with the one exception being that the prompt is
-  // closed as soon as the WebUI reset dialog is opened, we do not wait until
-  // the user actually makes a choice in that dialog.
-  void BeginResetPromptFlow();
-
-  // Called back by the ProfileResetter once resetting the profile settings has
-  // been completed, when requested by the user from inside the reset bubble.
-  // Will dismiss the prompt and conclude the reset prompt flow.
-  void OnProfileSettingsResetCompleted();
-
-  // Reports the result of triggering the prompt through UMA. Virtual, so it can
-  // be mocked out in tests to verify that the correct value is being reported.
-  virtual void ReportPromptResult(PromptResult result);
-
-  // Writes the memento values returned by the evaluation program to disk, and
-  // then destroys |evaluation_results_|.
-  void PersistMementos();
-
-  // Concludes the reset prompt flow.
-  void FinishResetPromptFlow();
-
-  Profile* profile_;
-
-  State state_;
-  bool enumeration_of_loaded_modules_ready_;
-  bool template_url_service_ready_;
-  bool has_already_dismissed_prompt_;
-
-  scoped_ptr<InputBuilder> input_builder_;
-  std::string hash_seed_;
-  std::string program_;
-
-  scoped_ptr<EvaluationResults> evaluation_results_;
-
-  bool should_show_reset_banner_;
-
-  scoped_ptr<AutomaticProfileResetterDelegate> delegate_;
-  scoped_refptr<base::TaskRunner> task_runner_for_waiting_;
-
-  base::WeakPtrFactory<AutomaticProfileResetter> weak_ptr_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(AutomaticProfileResetter);
-};
-
-#endif  // CHROME_BROWSER_PROFILE_RESETTER_AUTOMATIC_PROFILE_RESETTER_H_
diff --git a/chrome/browser/profile_resetter/automatic_profile_resetter_delegate.cc b/chrome/browser/profile_resetter/automatic_profile_resetter_delegate.cc
deleted file mode 100644
index b74329fd..0000000
--- a/chrome/browser/profile_resetter/automatic_profile_resetter_delegate.cc
+++ /dev/null
@@ -1,393 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/profile_resetter/automatic_profile_resetter_delegate.h"
-
-#include <string>
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/callback.h"
-#include "base/logging.h"
-#include "base/md5.h"
-#include "base/memory/scoped_vector.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_util.h"
-#include "base/values.h"
-#include "chrome/app/chrome_command_ids.h"
-#include "chrome/browser/chrome_notification_types.h"
-#include "chrome/browser/google/google_brand.h"
-#include "chrome/browser/profile_resetter/brandcode_config_fetcher.h"
-#include "chrome/browser/profile_resetter/profile_reset_global_error.h"
-#include "chrome/browser/profile_resetter/profile_resetter.h"
-#include "chrome/browser/profile_resetter/resettable_settings_snapshot.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/search_engines/template_url_service_factory.h"
-#include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/browser_finder.h"
-#include "chrome/browser/ui/global_error/global_error_service.h"
-#include "chrome/browser/ui/global_error/global_error_service_factory.h"
-#include "components/search_engines/template_url_prepopulate_data.h"
-#include "components/search_engines/template_url_service.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/notification_service.h"
-
-#if defined(OS_WIN)
-#include "chrome/browser/enumerate_modules_model_win.h"
-#endif
-
-namespace {
-
-scoped_ptr<base::DictionaryValue> BuildSubTreeFromTemplateURL(
-    const TemplateURL* template_url) {
-  // If this value contains a placeholder in the pre-populated data, it will
-  // have been replaced as it was loaded into a TemplateURL.
-  // BuildSubTreeFromTemplateURL works with TemplateURL (not TemplateURLData)
-  // in order to maintain this behaviour.
-  // TODO(engedy): Confirm the expected behaviour and convert to use
-  // TemplateURLData if possible."
-  scoped_ptr<base::DictionaryValue> tree(new base::DictionaryValue);
-  tree->SetString("name", template_url->short_name());
-  tree->SetString("short_name", template_url->short_name());
-  tree->SetString("keyword", template_url->keyword());
-  tree->SetString("search_url", template_url->url());
-  tree->SetString("url", template_url->url());
-  tree->SetString("suggestions_url", template_url->suggestions_url());
-  tree->SetString("instant_url", template_url->instant_url());
-  tree->SetString("image_url", template_url->image_url());
-  tree->SetString("new_tab_url", template_url->new_tab_url());
-  tree->SetString("search_url_post_params",
-                  template_url->search_url_post_params());
-  tree->SetString("suggestions_url_post_params",
-                  template_url->suggestions_url_post_params());
-  tree->SetString("instant_url_post_params",
-                  template_url->instant_url_post_params());
-  tree->SetString("image_url_post_params",
-                  template_url->image_url_post_params());
-  base::ListValue* alternate_urls = new base::ListValue;
-  alternate_urls->AppendStrings(template_url->alternate_urls());
-  tree->Set("alternate_urls", alternate_urls);
-  tree->SetString("favicon_url", template_url->favicon_url().spec());
-  tree->SetString("originating_url", template_url->originating_url().spec());
-  tree->SetBoolean("safe_for_autoreplace",
-                   template_url->safe_for_autoreplace());
-  base::ListValue* input_encodings = new base::ListValue;
-  input_encodings->AppendStrings(template_url->input_encodings());
-  tree->Set("input_encodings", input_encodings);
-  tree->SetString("id", base::Int64ToString(template_url->id()));
-  tree->SetString("date_created",
-                  base::Int64ToString(
-                      template_url->date_created().ToInternalValue()));
-  tree->SetString("last_modified",
-                  base::Int64ToString(
-                      template_url->last_modified().ToInternalValue()));
-  tree->SetBoolean("created_by_policy", template_url->created_by_policy());
-  tree->SetInteger("usage_count", template_url->usage_count());
-  tree->SetInteger("prepopulate_id", template_url->prepopulate_id());
-  tree->SetString("search_terms_replacement_key",
-                  template_url->search_terms_replacement_key());
-  return tree.Pass();
-}
-
-#if defined(OS_WIN)
-void ExtractLoadedModuleNameDigests(
-    const base::ListValue& module_list,
-    base::ListValue* module_name_digests) {
-  DCHECK(module_name_digests);
-
-  // EnumerateModulesModel produces a list of dictionaries.
-  // Each dictionary corresponds to a module and exposes a number of properties.
-  // We care only about 'type' and 'name'.
-  for (size_t i = 0; i < module_list.GetSize(); ++i) {
-    const base::DictionaryValue* module_dictionary = NULL;
-    if (!module_list.GetDictionary(i, &module_dictionary))
-      continue;
-    ModuleEnumerator::ModuleType module_type =
-        ModuleEnumerator::LOADED_MODULE;
-    if (!module_dictionary->GetInteger(
-            "type", reinterpret_cast<int*>(&module_type)) ||
-        module_type != ModuleEnumerator::LOADED_MODULE) {
-      continue;
-    }
-    std::string module_name;
-    if (!module_dictionary->GetString("name", &module_name))
-      continue;
-    module_name = base::ToLowerASCII(module_name);
-    module_name_digests->AppendString(base::MD5String(module_name));
-  }
-}
-#endif
-
-}  // namespace
-
-
-// AutomaticProfileResetterDelegateImpl --------------------------------------
-
-AutomaticProfileResetterDelegateImpl::AutomaticProfileResetterDelegateImpl(
-    Profile* profile,
-    ProfileResetter::ResettableFlags resettable_aspects)
-    : profile_(profile),
-      global_error_service_(GlobalErrorServiceFactory::GetForProfile(profile_)),
-      template_url_service_(TemplateURLServiceFactory::GetForProfile(profile_)),
-      resettable_aspects_(resettable_aspects) {
-  DCHECK(profile_);
-  if (template_url_service_) {
-    template_url_service_->AddObserver(this);
-    // Needed so that |template_url_service_ready_event_| will be signaled even
-    // when TemplateURLService had been already initialized before this point.
-    OnTemplateURLServiceChanged();
-  }
-
-#if defined(OS_WIN)
-  module_list_.reset(EnumerateModulesModel::GetInstance()->GetModuleList());
-#endif
-  if (module_list_) {
-    // Having a non-empty module list proves that enumeration had been already
-    // performed before this point.
-    modules_have_been_enumerated_event_.Signal();
-  }
-  registrar_.Add(this,
-                 chrome::NOTIFICATION_MODULE_LIST_ENUMERATED,
-                 content::NotificationService::AllSources());
-}
-
-AutomaticProfileResetterDelegateImpl::~AutomaticProfileResetterDelegateImpl() {
-  if (template_url_service_)
-    template_url_service_->RemoveObserver(this);
-}
-
-void AutomaticProfileResetterDelegateImpl::EnumerateLoadedModulesIfNeeded() {
-  if (!modules_have_been_enumerated_event_.is_signaled()) {
-#if defined(OS_WIN)
-    EnumerateModulesModel::GetInstance()->ScanNow();
-#else
-    modules_have_been_enumerated_event_.Signal();
-#endif
-  }
-}
-
-void AutomaticProfileResetterDelegateImpl::
-    RequestCallbackWhenLoadedModulesAreEnumerated(
-    const base::Closure& ready_callback) const {
-  DCHECK(!ready_callback.is_null());
-  modules_have_been_enumerated_event_.Post(FROM_HERE, ready_callback);
-}
-
-void AutomaticProfileResetterDelegateImpl::LoadTemplateURLServiceIfNeeded() {
-  DCHECK(template_url_service_);
-  template_url_service_->Load();  // Safe to call even if it has loaded already.
-}
-
-void AutomaticProfileResetterDelegateImpl::
-    RequestCallbackWhenTemplateURLServiceIsLoaded(
-    const base::Closure& ready_callback) const {
-  DCHECK(!ready_callback.is_null());
-  template_url_service_ready_event_.Post(FROM_HERE, ready_callback);
-}
-
-void AutomaticProfileResetterDelegateImpl::
-    FetchBrandcodedDefaultSettingsIfNeeded() {
-  if (brandcoded_config_fetcher_ ||
-      brandcoded_defaults_fetched_event_.is_signaled())
-    return;
-
-  std::string brandcode;
-  google_brand::GetBrand(&brandcode);
-  if (brandcode.empty()) {
-    brandcoded_defaults_.reset(new BrandcodedDefaultSettings);
-    brandcoded_defaults_fetched_event_.Signal();
-  } else {
-    brandcoded_config_fetcher_.reset(new BrandcodeConfigFetcher(
-        base::Bind(
-            &AutomaticProfileResetterDelegateImpl::OnBrandcodedDefaultsFetched,
-            base::Unretained(this)),
-        GURL("https://tools.google.com/service/update2"),
-        brandcode));
-  }
-}
-
-void AutomaticProfileResetterDelegateImpl::
-    RequestCallbackWhenBrandcodedDefaultsAreFetched(
-    const base::Closure& ready_callback) const {
-  DCHECK(!ready_callback.is_null());
-  brandcoded_defaults_fetched_event_.Post(FROM_HERE, ready_callback);
-}
-
-scoped_ptr<base::ListValue> AutomaticProfileResetterDelegateImpl::
-    GetLoadedModuleNameDigests() const {
-  DCHECK(modules_have_been_enumerated_event_.is_signaled());
-  scoped_ptr<base::ListValue> result(new base::ListValue);
-#if defined(OS_WIN)
-  if (module_list_)
-    ExtractLoadedModuleNameDigests(*module_list_, result.get());
-#endif
-  return result.Pass();
-}
-
-scoped_ptr<base::DictionaryValue> AutomaticProfileResetterDelegateImpl::
-    GetDefaultSearchProviderDetails() const {
-  DCHECK(template_url_service_);
-  DCHECK(template_url_service_->loaded());
-
-  const TemplateURL* default_search_provider =
-      template_url_service_->GetDefaultSearchProvider();
-
-  // Having a NULL default search provider is due to either:
-  //  1.) default search providers being disabled by policy,
-  //  2.) directly tampering with the Preferences and/or the SQLite DBs.
-  // In this state, Omnibox non-keyword search functionality is disabled.
-  return default_search_provider ?
-      BuildSubTreeFromTemplateURL(default_search_provider) :
-      scoped_ptr<base::DictionaryValue>(new base::DictionaryValue);
-}
-
-bool AutomaticProfileResetterDelegateImpl::
-    IsDefaultSearchProviderManaged() const {
-  DCHECK(template_url_service_);
-  DCHECK(template_url_service_->loaded());
-  return template_url_service_->is_default_search_managed();
-}
-
-scoped_ptr<base::ListValue> AutomaticProfileResetterDelegateImpl::
-    GetPrepopulatedSearchProvidersDetails() const {
-  size_t default_search_index = 0;
-  ScopedVector<TemplateURLData> engines(
-      TemplateURLPrepopulateData::GetPrepopulatedEngines(
-          profile_->GetPrefs(), &default_search_index));
-  scoped_ptr<base::ListValue> engines_details_list(new base::ListValue);
-  for (ScopedVector<TemplateURLData>::const_iterator it = engines.begin();
-       it != engines.end(); ++it) {
-    TemplateURL template_url(**it);
-    engines_details_list->Append(
-        BuildSubTreeFromTemplateURL(&template_url).release());
-  }
-  return engines_details_list.Pass();
-}
-
-bool AutomaticProfileResetterDelegateImpl::TriggerPrompt() {
-  DCHECK(global_error_service_);
-
-  Browser* browser = chrome::FindTabbedBrowser(
-      profile_, false /*match_original_profiles*/, chrome::GetActiveDesktop());
-  if (!browser || !ProfileResetGlobalError::IsSupportedOnPlatform(browser))
-    return false;
-
-  ProfileResetGlobalError* global_error = new ProfileResetGlobalError(profile_);
-  global_error_service_->AddGlobalError(global_error);
-
-  // Do not try to show bubble if another GlobalError is already showing one.
-  const GlobalErrorService::GlobalErrorList& global_errors(
-      global_error_service_->errors());
-  GlobalErrorService::GlobalErrorList::const_iterator it;
-  for (it = global_errors.begin(); it != global_errors.end(); ++it) {
-    if ((*it)->GetBubbleView())
-      break;
-  }
-  if (it == global_errors.end())
-    global_error->ShowBubbleView(browser);
-  return true;
-}
-
-void AutomaticProfileResetterDelegateImpl::TriggerProfileSettingsReset(
-    bool send_feedback,
-    const base::Closure& completion) {
-  DCHECK(!profile_resetter_);
-  DCHECK(!completion.is_null());
-
-  profile_resetter_.reset(new ProfileResetter(profile_));
-  FetchBrandcodedDefaultSettingsIfNeeded();
-  RequestCallbackWhenBrandcodedDefaultsAreFetched(base::Bind(
-      &AutomaticProfileResetterDelegateImpl::RunProfileSettingsReset,
-      AsWeakPtr(),
-      send_feedback,
-      completion));
-}
-
-void AutomaticProfileResetterDelegateImpl::OnTemplateURLServiceChanged() {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  DCHECK(template_url_service_);
-  if (template_url_service_->loaded() &&
-      !template_url_service_ready_event_.is_signaled())
-    template_url_service_ready_event_.Signal();
-}
-
-void AutomaticProfileResetterDelegateImpl::DismissPrompt() {
-  DCHECK(global_error_service_);
-  GlobalError* global_error =
-      global_error_service_->GetGlobalErrorByMenuItemCommandID(
-          IDC_SHOW_SETTINGS_RESET_BUBBLE);
-  if (global_error) {
-    // This will also close/destroy the Bubble UI if it is currently shown.
-    global_error_service_->RemoveGlobalError(global_error);
-    delete global_error;
-  }
-}
-
-void AutomaticProfileResetterDelegateImpl::Observe(
-    int type,
-    const content::NotificationSource& source,
-    const content::NotificationDetails& details) {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  if (type == chrome::NOTIFICATION_MODULE_LIST_ENUMERATED &&
-      !modules_have_been_enumerated_event_.is_signaled()) {
-#if defined(OS_WIN)
-    module_list_.reset(EnumerateModulesModel::GetInstance()->GetModuleList());
-#endif
-    modules_have_been_enumerated_event_.Signal();
-  }
-}
-
-void AutomaticProfileResetterDelegateImpl::SendFeedback(
-    const std::string& report) const {
-  SendSettingsFeedback(report, profile_, PROFILE_RESET_PROMPT);
-}
-
-void AutomaticProfileResetterDelegateImpl::RunProfileSettingsReset(
-    bool send_feedback,
-    const base::Closure& completion) {
-  DCHECK(brandcoded_defaults_);
-  scoped_ptr<ResettableSettingsSnapshot> old_settings_snapshot;
-  if (send_feedback) {
-    old_settings_snapshot.reset(new ResettableSettingsSnapshot(profile_));
-    old_settings_snapshot->RequestShortcuts(base::Closure());
-  }
-  profile_resetter_->Reset(resettable_aspects_,
-                           brandcoded_defaults_.Pass(),
-                           send_feedback,
-                           base::Bind(&AutomaticProfileResetterDelegateImpl::
-                                          OnProfileSettingsResetCompleted,
-                                      AsWeakPtr(),
-                                      completion,
-                                      base::Passed(&old_settings_snapshot)));
-}
-
-void AutomaticProfileResetterDelegateImpl::
-    OnBrandcodedDefaultsFetched() {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  DCHECK(brandcoded_config_fetcher_);
-  DCHECK(!brandcoded_config_fetcher_->IsActive());
-  brandcoded_defaults_ = brandcoded_config_fetcher_->GetSettings();
-  if (!brandcoded_defaults_)
-    brandcoded_defaults_.reset(new BrandcodedDefaultSettings);
-  brandcoded_defaults_fetched_event_.Signal();
-}
-
-void AutomaticProfileResetterDelegateImpl::OnProfileSettingsResetCompleted(
-    const base::Closure& user_callback,
-    scoped_ptr<ResettableSettingsSnapshot> old_settings_snapshot) {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  if (old_settings_snapshot) {
-    ResettableSettingsSnapshot new_settings_snapshot(profile_);
-    int difference =
-        old_settings_snapshot->FindDifferentFields(new_settings_snapshot);
-    if (difference) {
-      old_settings_snapshot->Subtract(new_settings_snapshot);
-      std::string report =
-          SerializeSettingsReport(*old_settings_snapshot, difference);
-      SendFeedback(report);
-    }
-  }
-  content::BrowserThread::PostTask(
-      content::BrowserThread::UI, FROM_HERE, user_callback);
-}
diff --git a/chrome/browser/profile_resetter/automatic_profile_resetter_delegate.h b/chrome/browser/profile_resetter/automatic_profile_resetter_delegate.h
deleted file mode 100644
index 73a660b6..0000000
--- a/chrome/browser/profile_resetter/automatic_profile_resetter_delegate.h
+++ /dev/null
@@ -1,237 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Declares a delegate that interacts with the rest of the browser on behalf of
-// the AutomaticProfileResetter.
-//
-// The reason for this separation is to facilitate unit testing. Factoring out
-// the implementation for each interaction step (encapsulated by one method of
-// the delegate) allows it to be tested independently in itself. It also becomes
-// easier to verify that the state machine inside AutomaticProfileResetter works
-// correctly: by mocking out the interaction methods in the delegate, we can, in
-// effect, mock out the entire rest of the browser, allowing us to easily
-// simulate scenarios that are interesting for testing the state machine.
-//
-// The delegate is normally instantiated by AutomaticProfileResetter internally,
-// while a mock implementation can be injected during unit tests.
-
-#ifndef CHROME_BROWSER_PROFILE_RESETTER_AUTOMATIC_PROFILE_RESETTER_DELEGATE_H_
-#define CHROME_BROWSER_PROFILE_RESETTER_AUTOMATIC_PROFILE_RESETTER_DELEGATE_H_
-
-#include "base/basictypes.h"
-#include "base/callback_forward.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/memory/weak_ptr.h"
-#include "chrome/browser/profile_resetter/profile_resetter.h"
-#include "components/search_engines/template_url_service_observer.h"
-#include "content/public/browser/notification_observer.h"
-#include "content/public/browser/notification_registrar.h"
-#include "extensions/common/one_shot_event.h"
-
-class BrandcodeConfigFetcher;
-class GlobalErrorService;
-class Profile;
-class ResettableSettingsSnapshot;
-class TemplateURLService;
-
-namespace base {
-class DictionaryValue;
-class ListValue;
-}
-
-// Defines the interface for the delegate that will interact with the rest of
-// the browser on behalf of the AutomaticProfileResetter.
-class AutomaticProfileResetterDelegate {
- public:
-  virtual ~AutomaticProfileResetterDelegate() {}
-
-  // Requests the module enumerator to start scanning for loaded modules now, if
-  // it has not done so already.
-  virtual void EnumerateLoadedModulesIfNeeded() = 0;
-
-  // Requests |ready_callback| to be posted on the UI thread once the module
-  // enumerator has finished scanning for loaded modules.
-  virtual void RequestCallbackWhenLoadedModulesAreEnumerated(
-      const base::Closure& ready_callback) const = 0;
-
-  // Requests the template URL service to load its database (asynchronously).
-  virtual void LoadTemplateURLServiceIfNeeded() = 0;
-
-  // Requests |ready_callback| to be posted on the UI thread once the template
-  // URL service has finished loading its database.
-  virtual void RequestCallbackWhenTemplateURLServiceIsLoaded(
-      const base::Closure& ready_callback) const = 0;
-
-  // Starts downloading the configuration file that specifies the default
-  // settings for the current brandcode; or establishes that we are running a
-  // vanilla (non-branded) build.
-  virtual void FetchBrandcodedDefaultSettingsIfNeeded() = 0;
-
-  // Requests |ready_callback| to be posted on the UI thread once the brandcoded
-  // default settings have been downloaded, or once it has been established that
-  // we are running a vanilla (non-branded) build.
-  virtual void RequestCallbackWhenBrandcodedDefaultsAreFetched(
-      const base::Closure& ready_callback) const = 0;
-
-  // Returns a list of loaded module name digests.
-  virtual scoped_ptr<base::ListValue> GetLoadedModuleNameDigests() const = 0;
-
-  // Returns attributes of the search engine currently set as the default (or
-  // an empty dictionary if there is none).
-  // The dictionary is in the same format as persisted to preferences by
-  // DefaultSearchManager::SetUserSelectedDefaultSearchEngine.
-  virtual scoped_ptr<base::DictionaryValue>
-      GetDefaultSearchProviderDetails() const = 0;
-
-  // Returns whether or not the default search provider is set by policy.
-  virtual bool IsDefaultSearchProviderManaged() const = 0;
-
-  // Returns a list of dictionaries, each containing attributes for each of the
-  // pre-populated search engines, in the format described above.
-  virtual scoped_ptr<base::ListValue>
-      GetPrepopulatedSearchProvidersDetails() const = 0;
-
-  // Triggers showing the one-time profile settings reset prompt, which consists
-  // of two parts: (1.) the profile reset (pop-up) bubble, and (2.) a menu item
-  // in the wrench menu. Showing the bubble might be delayed if there is another
-  // bubble currently shown, in which case the bubble will be shown the first
-  // time a new browser window is opened.
-  // Returns true unless the reset prompt is not supported on the current
-  // platform, in which case it returns false and does nothing.
-  virtual bool TriggerPrompt() = 0;
-
-  // Triggers the ProfileResetter to reset all supported settings and optionally
-  // |send_feedback|. Will post |completion| on the UI thread once completed.
-  // Brandcoded default settings will be fetched if they are not yet available,
-  // the reset will be performed once the download is complete.
-  // NOTE: Should only be called at most once during the lifetime of the object.
-  virtual void TriggerProfileSettingsReset(bool send_feedback,
-                                           const base::Closure& completion) = 0;
-
-  // Dismisses the one-time profile settings reset prompt, if it is currently
-  // triggered. Will synchronously destroy the corresponding GlobalError.
-  virtual void DismissPrompt() = 0;
-};
-
-// Implementation for AutomaticProfileResetterDelegate.
-class AutomaticProfileResetterDelegateImpl
-    : public AutomaticProfileResetterDelegate,
-      public base::SupportsWeakPtr<AutomaticProfileResetterDelegateImpl>,
-      public TemplateURLServiceObserver,
-      public content::NotificationObserver {
- public:
-  explicit AutomaticProfileResetterDelegateImpl(
-      Profile* profile,
-      ProfileResetter::ResettableFlags resettable_aspects);
-  ~AutomaticProfileResetterDelegateImpl() override;
-
-  // Returns the brandcoded default settings; empty defaults if this is not a
-  // branded build; or NULL if FetchBrandcodedDefaultSettingsIfNeeded() has not
-  // yet been called or not yet finished. Exposed only for unit tests.
-  const BrandcodedDefaultSettings* brandcoded_defaults() const {
-    return brandcoded_defaults_.get();
-  }
-
-  // AutomaticProfileResetterDelegate:
-  void EnumerateLoadedModulesIfNeeded() override;
-  void RequestCallbackWhenLoadedModulesAreEnumerated(
-      const base::Closure& ready_callback) const override;
-  void LoadTemplateURLServiceIfNeeded() override;
-  void RequestCallbackWhenTemplateURLServiceIsLoaded(
-      const base::Closure& ready_callback) const override;
-  void FetchBrandcodedDefaultSettingsIfNeeded() override;
-  void RequestCallbackWhenBrandcodedDefaultsAreFetched(
-      const base::Closure& ready_callback) const override;
-  scoped_ptr<base::ListValue> GetLoadedModuleNameDigests() const override;
-  scoped_ptr<base::DictionaryValue> GetDefaultSearchProviderDetails()
-      const override;
-  bool IsDefaultSearchProviderManaged() const override;
-  scoped_ptr<base::ListValue> GetPrepopulatedSearchProvidersDetails()
-      const override;
-  bool TriggerPrompt() override;
-  void TriggerProfileSettingsReset(bool send_feedback,
-                                   const base::Closure& completion) override;
-  void DismissPrompt() override;
-
-  // TemplateURLServiceObserver:
-  void OnTemplateURLServiceChanged() override;
-
-  // content::NotificationObserver:
-  void Observe(int type,
-               const content::NotificationSource& source,
-               const content::NotificationDetails& details) override;
-
- private:
-  // Sends a feedback |report|, where |report| is supposed to be result of
-  // ::SerializeSettingsReport(). Virtual, so it can be mocked out for tests.
-  virtual void SendFeedback(const std::string& report) const;
-
-  // Triggers the ProfileResetter to reset |resettable_aspects_| and optionally
-  // |send_feedback|. Will invoke |completion| on the UI thread once completed
-  // The |brandcoded_defaults_| must already be initialized when this is called.
-  void RunProfileSettingsReset(bool send_feedback,
-                               const base::Closure& completion);
-
-  // Called by |brandcoded_config_fetcher_| when it finishes downloading the
-  // brandcoded default settings (or the download times out).
-  void OnBrandcodedDefaultsFetched();
-
-  // Called back by the ProfileResetter once resetting the profile settings has
-  // been completed. If |old_settings_snapshot| is non-NULL, will compare it to
-  // the new settings and send the differences to Google for analysis. Finally,
-  // will post |user_callback|.
-  void OnProfileSettingsResetCompleted(
-      const base::Closure& user_callback,
-      scoped_ptr<ResettableSettingsSnapshot> old_settings_snapshot);
-
-  // The profile that this delegate operates on.
-  Profile* profile_;
-
-  // Shortcuts to |profile_| keyed services, to reduce boilerplate. These may be
-  // NULL in unit tests that do not initialize the respective service(s).
-  GlobalErrorService* global_error_service_;
-  TemplateURLService* template_url_service_;
-
-  // Helper to asynchronously download the default settings for the current
-  // distribution channel (identified by brand code). Instantiated on-demand.
-  scoped_ptr<BrandcodeConfigFetcher> brandcoded_config_fetcher_;
-
-  // Once |brandcoded_defaults_fetched_event_| has fired, this will contain the
-  // brandcoded default settings, or empty settings for a non-branded build.
-  scoped_ptr<BrandcodedDefaultSettings> brandcoded_defaults_;
-
-  // Overwritten to avoid resetting aspects that will not work in unit tests.
-  const ProfileResetter::ResettableFlags resettable_aspects_;
-
-  // The profile resetter to perform the actual reset. Instantiated on-demand.
-  scoped_ptr<ProfileResetter> profile_resetter_;
-
-  // Manages registrations/unregistrations for notifications.
-  content::NotificationRegistrar registrar_;
-
-  // The list of modules found. Even when |modules_have_been_enumerated_event_|
-  // is signaled, this may still be NULL.
-  scoped_ptr<base::ListValue> module_list_;
-
-  // This event is signaled once module enumeration has been attempted. If
-  // during construction, EnumerateModulesModel can supply a non-empty list of
-  // modules, module enumeration has clearly already happened, so the event will
-  // be signaled immediately; otherwise, when EnumerateLoadedModulesIfNeeded()
-  // is called, it will ask the model to scan the modules, and then signal the
-  // event once this process is completed.
-  extensions::OneShotEvent modules_have_been_enumerated_event_;
-
-  // This event is signaled once the TemplateURLService has loaded.  If the
-  // TemplateURLService was already loaded prior to the creation of this class,
-  // the event will be signaled during construction.
-  extensions::OneShotEvent template_url_service_ready_event_;
-
-  // This event is signaled once brandcoded default settings have been fetched,
-  // or once it has been established that this is not a branded build.
-  extensions::OneShotEvent brandcoded_defaults_fetched_event_;
-
-  DISALLOW_COPY_AND_ASSIGN(AutomaticProfileResetterDelegateImpl);
-};
-
-#endif  // CHROME_BROWSER_PROFILE_RESETTER_AUTOMATIC_PROFILE_RESETTER_DELEGATE_H_
diff --git a/chrome/browser/profile_resetter/automatic_profile_resetter_delegate_unittest.cc b/chrome/browser/profile_resetter/automatic_profile_resetter_delegate_unittest.cc
deleted file mode 100644
index 9214100..0000000
--- a/chrome/browser/profile_resetter/automatic_profile_resetter_delegate_unittest.cc
+++ /dev/null
@@ -1,608 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/profile_resetter/automatic_profile_resetter_delegate.h"
-
-#include <algorithm>
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/prefs/pref_service.h"
-#include "base/run_loop.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_split.h"
-#include "base/strings/string_util.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/test/values_test_util.h"
-#include "base/values.h"
-#include "chrome/app/chrome_command_ids.h"
-#include "chrome/browser/chrome_notification_types.h"
-#include "chrome/browser/extensions/extension_service.h"
-#include "chrome/browser/extensions/extension_service_test_base.h"
-#include "chrome/browser/google/google_brand.h"
-#include "chrome/browser/profile_resetter/brandcoded_default_settings.h"
-#include "chrome/browser/profile_resetter/profile_reset_global_error.h"
-#include "chrome/browser/search_engines/template_url_service_factory.h"
-#include "chrome/browser/search_engines/template_url_service_factory_test_util.h"
-#include "chrome/browser/ui/global_error/global_error.h"
-#include "chrome/browser/ui/global_error/global_error_service.h"
-#include "chrome/browser/ui/global_error/global_error_service_factory.h"
-#include "chrome/common/pref_names.h"
-#include "chrome/test/base/testing_profile.h"
-#include "components/search_engines/default_search_manager.h"
-#include "components/search_engines/template_url_prepopulate_data.h"
-#include "components/search_engines/template_url_service.h"
-#include "components/syncable_prefs/testing_pref_service_syncable.h"
-#include "content/public/browser/notification_service.h"
-#include "net/http/http_response_headers.h"
-#include "net/url_request/test_url_fetcher_factory.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-#if defined(OS_WIN)
-#include "chrome/browser/enumerate_modules_model_win.h"
-#endif
-
-namespace {
-
-const char kTestBrandcode[] = "FOOBAR";
-
-const char kTestHomepage[] = "http://google.com";
-const char kTestBrandedHomepage[] = "http://example.com";
-
-const ProfileResetter::ResettableFlags kResettableAspectsForTest =
-    ProfileResetter::ALL & ~ProfileResetter::COOKIES_AND_SITE_DATA;
-
-// Helpers -------------------------------------------------------------------
-
-// A testing version of the AutomaticProfileResetterDelegate that differs from
-// the real one only in that it has its feedback reporting mocked out, and it
-// will not reset COOKIES_AND_SITE_DATA, due to difficulties to set up some
-// required URLRequestContexts in unit tests.
-class AutomaticProfileResetterDelegateUnderTest
-    : public AutomaticProfileResetterDelegateImpl {
- public:
-  explicit AutomaticProfileResetterDelegateUnderTest(Profile* profile)
-      : AutomaticProfileResetterDelegateImpl(
-            profile, kResettableAspectsForTest) {}
-  virtual ~AutomaticProfileResetterDelegateUnderTest() {}
-
-  MOCK_CONST_METHOD1(SendFeedback, void(const std::string&));
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(AutomaticProfileResetterDelegateUnderTest);
-};
-
-class MockCallbackTarget {
- public:
-  MockCallbackTarget() {}
-  ~MockCallbackTarget() {}
-
-  MOCK_CONST_METHOD0(Run, void(void));
-
-  base::Closure CreateClosure() {
-    return base::Bind(&MockCallbackTarget::Run, base::Unretained(this));
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(MockCallbackTarget);
-};
-
-// Returns the details of the default search provider from |prefs| in a format
-// suitable for usage as |expected_details| in ExpectDetailsMatch().
-const base::DictionaryValue* GetDefaultSearchProviderDetailsFromPrefs(
-    const PrefService* prefs) {
-  return prefs->GetDictionary(
-      DefaultSearchManager::kDefaultSearchProviderDataPrefName);
-}
-
-// Verifies that the |details| of a search engine as provided by the delegate
-// are correct in comparison to the |expected_details| coming from the Prefs.
-void ExpectDetailsMatch(const base::DictionaryValue& expected_details,
-                        const base::DictionaryValue& details) {
-  for (base::DictionaryValue::Iterator it(expected_details); !it.IsAtEnd();
-       it.Advance()) {
-    SCOPED_TRACE(testing::Message("Key: ") << it.key());
-    if (it.key() == "enabled" || it.key() == "synced_guid") {
-      // These attributes should not be present.
-      EXPECT_FALSE(details.HasKey(it.key()));
-      continue;
-    }
-    const base::Value* expected_value = &it.value();
-    const base::Value* actual_value = NULL;
-    ASSERT_TRUE(details.Get(it.key(), &actual_value));
-
-    // Ignore ID as it is dynamically assigned by the TemplateURLService.
-    // last_modified may get updated during a run, so ignore value differences.
-    if (it.key() != "id" && it.key() != "last_modified") {
-      // Everything else is the same format.
-      EXPECT_TRUE(actual_value->Equals(expected_value))
-          << "Expected: " << *expected_value << ". Actual: " << *actual_value;
-    }
-  }
-}
-
-// If |simulate_failure| is false, then replies to the pending request on
-// |fetcher| with a brandcoded config that only specifies a home page URL.
-// If |simulate_failure| is true, replies with 404.
-void ServicePendingBrancodedConfigFetch(net::TestURLFetcher* fetcher,
-                                        bool simulate_failure) {
-  const char kBrandcodedXmlSettings[] =
-      "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
-      "<response protocol=\"3.0\" server=\"prod\">"
-        "<app appid=\"{8A69D345-D564-463C-AFF1-A69D9E530F96}\" status=\"ok\">"
-          "<data index=\"skipfirstrunui-importsearch-defaultbrowser\" "
-          "name=\"install\" status=\"ok\">"
-            "{\"homepage\" : \"$1\"}"
-          "</data>"
-        "</app>"
-      "</response>";
-
-  fetcher->set_response_code(simulate_failure ? 404 : 200);
-  scoped_refptr<net::HttpResponseHeaders> response_headers(
-      new net::HttpResponseHeaders(""));
-  response_headers->AddHeader("Content-Type: text/xml");
-  fetcher->set_response_headers(response_headers);
-  if (!simulate_failure) {
-    std::string response(kBrandcodedXmlSettings);
-    size_t placeholder_index = response.find("$1");
-    ASSERT_NE(std::string::npos, placeholder_index);
-    response.replace(placeholder_index, 2, kTestBrandedHomepage);
-    fetcher->SetResponseString(response);
-  }
-  fetcher->delegate()->OnURLFetchComplete(fetcher);
-}
-
-
-// Test fixture --------------------------------------------------------------
-
-// ExtensionServiceTestBase sets up a TestingProfile with the ExtensionService,
-// we then add the TemplateURLService, so the ProfileResetter can be exercised.
-class AutomaticProfileResetterDelegateTest
-    : public extensions::ExtensionServiceTestBase {
- protected:
-  AutomaticProfileResetterDelegateTest() {}
-  ~AutomaticProfileResetterDelegateTest() override {}
-
-  void SetUp() override {
-    extensions::ExtensionServiceTestBase::SetUp();
-    ExtensionServiceInitParams params = CreateDefaultInitParams();
-    params.pref_file.clear();  // Prescribes a TestingPrefService to be created.
-    InitializeExtensionService(params);
-    template_url_service_test_util_.reset(
-        new TemplateURLServiceFactoryTestUtil(profile_.get()));
-    resetter_delegate_.reset(
-        new AutomaticProfileResetterDelegateUnderTest(profile()));
-  }
-
-  void TearDown() override {
-    resetter_delegate_.reset();
-    template_url_service_test_util_.reset();
-    extensions::ExtensionServiceTestBase::TearDown();
-  }
-
-  scoped_ptr<TemplateURL> CreateTestTemplateURL() {
-    TemplateURLData data;
-
-    data.SetURL("http://example.com/search?q={searchTerms}");
-    data.suggestions_url = "http://example.com/suggest?q={searchTerms}";
-    data.instant_url = "http://example.com/instant?q={searchTerms}";
-    data.image_url = "http://example.com/image?q={searchTerms}";
-    data.search_url_post_params = "search-post-params";
-    data.suggestions_url_post_params = "suggest-post-params";
-    data.instant_url_post_params = "instant-post-params";
-    data.image_url_post_params = "image-post-params";
-
-    data.favicon_url = GURL("http://example.com/favicon.ico");
-    data.new_tab_url = "http://example.com/newtab.html";
-    data.alternate_urls.push_back("http://example.com/s?q={searchTerms}");
-
-    data.short_name = base::ASCIIToUTF16("name");
-    data.SetKeyword(base::ASCIIToUTF16("keyword"));
-    data.search_terms_replacement_key = "search-terms-replacment-key";
-    data.prepopulate_id = 42;
-    data.input_encodings.push_back("UTF-8");
-    data.safe_for_autoreplace = true;
-
-    return scoped_ptr<TemplateURL>(new TemplateURL(data));
-  }
-
-  void ExpectNoPendingBrandcodedConfigFetch() {
-    EXPECT_FALSE(test_url_fetcher_factory_.GetFetcherByID(0));
-  }
-
-  void ExpectAndServicePendingBrandcodedConfigFetch(bool simulate_failure) {
-    net::TestURLFetcher* fetcher = test_url_fetcher_factory_.GetFetcherByID(0);
-    ASSERT_TRUE(fetcher);
-    EXPECT_THAT(fetcher->upload_data(),
-                testing::HasSubstr(kTestBrandcode));
-    ServicePendingBrancodedConfigFetch(fetcher, simulate_failure);
-  }
-
-  void ExpectResetPromptState(bool active) {
-    GlobalErrorService* global_error_service =
-        GlobalErrorServiceFactory::GetForProfile(profile());
-    GlobalError* global_error = global_error_service->
-        GetGlobalErrorByMenuItemCommandID(IDC_SHOW_SETTINGS_RESET_BUBBLE);
-    EXPECT_EQ(active, !!global_error);
-  }
-
-  AutomaticProfileResetterDelegateUnderTest* resetter_delegate() {
-    return resetter_delegate_.get();
-  }
-
-  TemplateURLServiceFactoryTestUtil* template_url_service_test_util() {
-    return template_url_service_test_util_.get();
-  }
-
- private:
-  scoped_ptr<TemplateURLServiceFactoryTestUtil> template_url_service_test_util_;
-  net::TestURLFetcherFactory test_url_fetcher_factory_;
-  scoped_ptr<AutomaticProfileResetterDelegateUnderTest> resetter_delegate_;
-
-  DISALLOW_COPY_AND_ASSIGN(AutomaticProfileResetterDelegateTest);
-};
-
-
-// Tests ---------------------------------------------------------------------
-
-TEST_F(AutomaticProfileResetterDelegateTest,
-       TriggerAndWaitOnModuleEnumeration) {
-  // Expect ready_callback to be called just after the modules have been
-  // enumerated. Fail if it is not called. Note: as the EnumerateModulesModel is
-  // a global singleton, the callback might be invoked immediately if another
-  // test-case (e.g. the one below) has already performed module enumeration.
-  testing::StrictMock<MockCallbackTarget> mock_target;
-  EXPECT_CALL(mock_target, Run());
-  resetter_delegate()->RequestCallbackWhenLoadedModulesAreEnumerated(
-      mock_target.CreateClosure());
-  resetter_delegate()->EnumerateLoadedModulesIfNeeded();
-  base::RunLoop().RunUntilIdle();
-
-  testing::Mock::VerifyAndClearExpectations(&mock_target);
-
-  // Expect ready_callback to be posted immediately when the modules have
-  // already been enumerated.
-  EXPECT_CALL(mock_target, Run());
-  resetter_delegate()->RequestCallbackWhenLoadedModulesAreEnumerated(
-      mock_target.CreateClosure());
-  base::RunLoop().RunUntilIdle();
-
-#if defined(OS_WIN)
-  testing::Mock::VerifyAndClearExpectations(&mock_target);
-
-  // Expect ready_callback to be posted immediately even when the modules had
-  // already been enumerated when the delegate was constructed.
-  scoped_ptr<AutomaticProfileResetterDelegate> late_resetter_delegate(
-      new AutomaticProfileResetterDelegateImpl(profile(),
-                                               ProfileResetter::ALL));
-
-  EXPECT_CALL(mock_target, Run());
-  late_resetter_delegate->RequestCallbackWhenLoadedModulesAreEnumerated(
-      mock_target.CreateClosure());
-  base::RunLoop().RunUntilIdle();
-#endif
-}
-
-TEST_F(AutomaticProfileResetterDelegateTest, GetLoadedModuleNameDigests) {
-  resetter_delegate()->EnumerateLoadedModulesIfNeeded();
-  base::RunLoop().RunUntilIdle();
-  scoped_ptr<base::ListValue> module_name_digests(
-      resetter_delegate()->GetLoadedModuleNameDigests());
-
-  // Just verify that each element looks like an MD5 hash in hexadecimal, and
-  // also that we have at least one element on Win.
-  ASSERT_TRUE(module_name_digests);
-  for (base::ListValue::const_iterator it = module_name_digests->begin();
-       it != module_name_digests->end(); ++it) {
-    std::string digest_hex;
-    std::vector<uint8> digest_raw;
-
-    ASSERT_TRUE((*it)->GetAsString(&digest_hex));
-    ASSERT_TRUE(base::HexStringToBytes(digest_hex, &digest_raw));
-    EXPECT_EQ(16u, digest_raw.size());
-  }
-#if defined(OS_WIN)
-  EXPECT_LE(1u, module_name_digests->GetSize());
-#endif
-}
-
-TEST_F(AutomaticProfileResetterDelegateTest, LoadAndWaitOnTemplateURLService) {
-  // Expect ready_callback to be called just after the template URL service gets
-  // initialized. Fail if it is not called, or called too early.
-  testing::StrictMock<MockCallbackTarget> mock_target;
-  resetter_delegate()->RequestCallbackWhenTemplateURLServiceIsLoaded(
-      mock_target.CreateClosure());
-  base::RunLoop().RunUntilIdle();
-
-  EXPECT_CALL(mock_target, Run());
-  resetter_delegate()->LoadTemplateURLServiceIfNeeded();
-  base::RunLoop().RunUntilIdle();
-
-  testing::Mock::VerifyAndClearExpectations(&mock_target);
-
-  // Expect ready_callback to be posted immediately when the template URL
-  // service is already initialized.
-  EXPECT_CALL(mock_target, Run());
-  resetter_delegate()->RequestCallbackWhenTemplateURLServiceIsLoaded(
-      mock_target.CreateClosure());
-  base::RunLoop().RunUntilIdle();
-
-  testing::Mock::VerifyAndClearExpectations(&mock_target);
-
-  // Expect ready_callback to be posted immediately even when the template URL
-  // service had already been initialized when the delegate was constructed.
-  scoped_ptr<AutomaticProfileResetterDelegate> late_resetter_delegate(
-      new AutomaticProfileResetterDelegateImpl(profile(),
-                                               ProfileResetter::ALL));
-
-  EXPECT_CALL(mock_target, Run());
-  late_resetter_delegate->RequestCallbackWhenTemplateURLServiceIsLoaded(
-      mock_target.CreateClosure());
-  base::RunLoop().RunUntilIdle();
-}
-
-TEST_F(AutomaticProfileResetterDelegateTest,
-       DefaultSearchProviderDataWhenNotManaged) {
-  TemplateURLService* template_url_service =
-      TemplateURLServiceFactory::GetForProfile(profile());
-  template_url_service_test_util()->VerifyLoad();
-
-  // Check that the "managed state" and the details returned by the delegate are
-  // correct. We verify the details against the data stored by
-  // TemplateURLService into Prefs.
-  scoped_ptr<TemplateURL> owned_custom_dsp(CreateTestTemplateURL());
-  TemplateURL* custom_dsp = owned_custom_dsp.get();
-  template_url_service->Add(owned_custom_dsp.release());
-  template_url_service->SetUserSelectedDefaultSearchProvider(custom_dsp);
-
-  PrefService* prefs = profile()->GetPrefs();
-  ASSERT_TRUE(prefs);
-  scoped_ptr<base::DictionaryValue> dsp_details(
-      resetter_delegate()->GetDefaultSearchProviderDetails());
-  const base::DictionaryValue* expected_dsp_details =
-      GetDefaultSearchProviderDetailsFromPrefs(prefs);
-
-  ExpectDetailsMatch(*expected_dsp_details, *dsp_details);
-  EXPECT_FALSE(resetter_delegate()->IsDefaultSearchProviderManaged());
-}
-
-TEST_F(AutomaticProfileResetterDelegateTest,
-       DefaultSearchProviderDataWhenManaged) {
-  const char kTestSearchURL[] = "http://example.com/search?q={searchTerms}";
-  const char kTestName[] = "name";
-  const char kTestKeyword[] = "keyword";
-
-  template_url_service_test_util()->VerifyLoad();
-
-  EXPECT_FALSE(resetter_delegate()->IsDefaultSearchProviderManaged());
-
-  // Set managed preferences to emulate a default search provider set by policy.
-  template_url_service_test_util()->SetManagedDefaultSearchPreferences(
-      true, kTestName, kTestKeyword, kTestSearchURL, std::string(),
-      std::string(), std::string(), std::string(), std::string());
-
-  EXPECT_TRUE(resetter_delegate()->IsDefaultSearchProviderManaged());
-  scoped_ptr<base::DictionaryValue> dsp_details(
-      resetter_delegate()->GetDefaultSearchProviderDetails());
-  // Checking that all details are correct is already done by the above test.
-  // Just make sure details are reported about the correct engine.
-  base::ExpectDictStringValue(kTestSearchURL, *dsp_details, "search_url");
-
-  // Set managed preferences to emulate that having a default search provider is
-  // disabled by policy.
-  template_url_service_test_util()->RemoveManagedDefaultSearchPreferences();
-  template_url_service_test_util()->SetManagedDefaultSearchPreferences(
-      false, std::string(), std::string(), std::string(), std::string(),
-      std::string(), std::string(), std::string(), std::string());
-
-  dsp_details = resetter_delegate()->GetDefaultSearchProviderDetails();
-  EXPECT_TRUE(resetter_delegate()->IsDefaultSearchProviderManaged());
-  EXPECT_TRUE(dsp_details->empty());
-}
-
-TEST_F(AutomaticProfileResetterDelegateTest,
-       GetPrepopulatedSearchProvidersDetails) {
-  TemplateURLService* template_url_service =
-      TemplateURLServiceFactory::GetForProfile(profile());
-  template_url_service_test_util()->VerifyLoad();
-
-  scoped_ptr<base::ListValue> search_engines_details(
-      resetter_delegate()->GetPrepopulatedSearchProvidersDetails());
-
-  // Do the same kind of verification as for GetDefaultSearchEngineDetails:
-  // subsequently set each pre-populated engine as the default, so we can verify
-  // that the details returned by the delegate about one particular engine are
-  // correct in comparison to what has been stored to the Prefs.
-  std::vector<TemplateURL*> prepopulated_engines =
-      template_url_service->GetTemplateURLs();
-
-  ASSERT_EQ(prepopulated_engines.size(), search_engines_details->GetSize());
-
-  for (size_t i = 0; i < search_engines_details->GetSize(); ++i) {
-    const base::DictionaryValue* details = NULL;
-    ASSERT_TRUE(search_engines_details->GetDictionary(i, &details));
-
-    std::string keyword;
-    ASSERT_TRUE(details->GetString("keyword", &keyword));
-    TemplateURL* search_engine =
-        template_url_service->GetTemplateURLForKeyword(
-            base::ASCIIToUTF16(keyword));
-    ASSERT_TRUE(search_engine);
-    template_url_service->SetUserSelectedDefaultSearchProvider(
-        prepopulated_engines[i]);
-
-    PrefService* prefs = profile()->GetPrefs();
-    ASSERT_TRUE(prefs);
-    const base::DictionaryValue* expected_dsp_details =
-        GetDefaultSearchProviderDetailsFromPrefs(prefs);
-    ExpectDetailsMatch(*expected_dsp_details, *details);
-  }
-}
-
-TEST_F(AutomaticProfileResetterDelegateTest,
-       FetchAndWaitOnDefaultSettingsVanilla) {
-  google_brand::BrandForTesting scoped_brand_for_testing((std::string()));
-
-  // Expect ready_callback to be called just after empty brandcoded settings
-  // are loaded, given this is a vanilla build. Fail if it is not called, or
-  // called too early.
-  testing::StrictMock<MockCallbackTarget> mock_target;
-  resetter_delegate()->RequestCallbackWhenBrandcodedDefaultsAreFetched(
-      mock_target.CreateClosure());
-  base::RunLoop().RunUntilIdle();
-  EXPECT_FALSE(resetter_delegate()->brandcoded_defaults());
-
-  EXPECT_CALL(mock_target, Run());
-  resetter_delegate()->FetchBrandcodedDefaultSettingsIfNeeded();
-  base::RunLoop().RunUntilIdle();
-  ExpectNoPendingBrandcodedConfigFetch();
-
-  testing::Mock::VerifyAndClearExpectations(&mock_target);
-  EXPECT_TRUE(resetter_delegate()->brandcoded_defaults());
-
-  // Expect ready_callback to be posted immediately when the brandcoded settings
-  // have already been loaded.
-  EXPECT_CALL(mock_target, Run());
-  resetter_delegate()->RequestCallbackWhenBrandcodedDefaultsAreFetched(
-      mock_target.CreateClosure());
-  base::RunLoop().RunUntilIdle();
-
-  // No test for a new instance of AutomaticProfileResetterDelegate. That will
-  // need to fetch the brandcoded settings again.
-}
-
-TEST_F(AutomaticProfileResetterDelegateTest,
-       FetchAndWaitOnDefaultSettingsBranded) {
-  google_brand::BrandForTesting scoped_brand_for_testing(kTestBrandcode);
-
-  // Expect ready_callback to be called just after the brandcoded settings are
-  // downloaded. Fail if it is not called, or called too early.
-  testing::StrictMock<MockCallbackTarget> mock_target;
-  resetter_delegate()->RequestCallbackWhenBrandcodedDefaultsAreFetched(
-      mock_target.CreateClosure());
-  base::RunLoop().RunUntilIdle();
-  EXPECT_FALSE(resetter_delegate()->brandcoded_defaults());
-
-  EXPECT_CALL(mock_target, Run());
-  resetter_delegate()->FetchBrandcodedDefaultSettingsIfNeeded();
-  ExpectAndServicePendingBrandcodedConfigFetch(false /*simulate_failure*/);
-  base::RunLoop().RunUntilIdle();
-
-  testing::Mock::VerifyAndClearExpectations(&mock_target);
-  const BrandcodedDefaultSettings* brandcoded_defaults =
-      resetter_delegate()->brandcoded_defaults();
-  ASSERT_TRUE(brandcoded_defaults);
-  std::string homepage_url;
-  EXPECT_TRUE(brandcoded_defaults->GetHomepage(&homepage_url));
-  EXPECT_EQ(kTestBrandedHomepage, homepage_url);
-
-  // Expect ready_callback to be posted immediately when the brandcoded settings
-  // have already been downloaded.
-  EXPECT_CALL(mock_target, Run());
-  resetter_delegate()->RequestCallbackWhenBrandcodedDefaultsAreFetched(
-      mock_target.CreateClosure());
-  base::RunLoop().RunUntilIdle();
-}
-
-TEST_F(AutomaticProfileResetterDelegateTest,
-       FetchAndWaitOnDefaultSettingsBrandedFailure) {
-  google_brand::BrandForTesting scoped_brand_for_testing(kTestBrandcode);
-
-  // Expect ready_callback to be called just after the brandcoded settings have
-  // failed to download. Fail if it is not called, or called too early.
-  testing::StrictMock<MockCallbackTarget> mock_target;
-  resetter_delegate()->RequestCallbackWhenBrandcodedDefaultsAreFetched(
-      mock_target.CreateClosure());
-  base::RunLoop().RunUntilIdle();
-
-  EXPECT_CALL(mock_target, Run());
-  resetter_delegate()->FetchBrandcodedDefaultSettingsIfNeeded();
-  ExpectAndServicePendingBrandcodedConfigFetch(true /*simulate_failure*/);
-  base::RunLoop().RunUntilIdle();
-
-  testing::Mock::VerifyAndClearExpectations(&mock_target);
-  EXPECT_TRUE(resetter_delegate()->brandcoded_defaults());
-
-  // Expect ready_callback to be posted immediately when the brandcoded settings
-  // have already been attempted to be downloaded, but failed.
-  EXPECT_CALL(mock_target, Run());
-  resetter_delegate()->RequestCallbackWhenBrandcodedDefaultsAreFetched(
-      mock_target.CreateClosure());
-  base::RunLoop().RunUntilIdle();
-}
-
-TEST_F(AutomaticProfileResetterDelegateTest, TriggerReset) {
-  google_brand::BrandForTesting scoped_brand_for_testing(kTestBrandcode);
-
-  PrefService* prefs = profile()->GetPrefs();
-  DCHECK(prefs);
-  prefs->SetString(prefs::kHomePage, kTestHomepage);
-
-  testing::StrictMock<MockCallbackTarget> mock_target;
-  EXPECT_CALL(mock_target, Run());
-  EXPECT_CALL(*resetter_delegate(), SendFeedback(testing::_)).Times(0);
-  resetter_delegate()->TriggerProfileSettingsReset(
-      false /*send_feedback*/, mock_target.CreateClosure());
-  ExpectAndServicePendingBrandcodedConfigFetch(false /*simulate_failure*/);
-  base::RunLoop().RunUntilIdle();
-
-  EXPECT_EQ(kTestBrandedHomepage, prefs->GetString(prefs::kHomePage));
-}
-
-TEST_F(AutomaticProfileResetterDelegateTest,
-       TriggerResetWithDefaultSettingsAlreadyLoaded) {
-  google_brand::BrandForTesting scoped_brand_for_testing(kTestBrandcode);
-
-  PrefService* prefs = profile()->GetPrefs();
-  DCHECK(prefs);
-  prefs->SetString(prefs::kHomePage, kTestHomepage);
-
-  resetter_delegate()->FetchBrandcodedDefaultSettingsIfNeeded();
-  ExpectAndServicePendingBrandcodedConfigFetch(false /*simulate_failure*/);
-  base::RunLoop().RunUntilIdle();
-
-  testing::StrictMock<MockCallbackTarget> mock_target;
-  EXPECT_CALL(mock_target, Run());
-  EXPECT_CALL(*resetter_delegate(), SendFeedback(testing::_)).Times(0);
-  resetter_delegate()->TriggerProfileSettingsReset(
-      false /*send_feedback*/, mock_target.CreateClosure());
-  base::RunLoop().RunUntilIdle();
-
-  EXPECT_EQ(kTestBrandedHomepage, prefs->GetString(prefs::kHomePage));
-}
-
-TEST_F(AutomaticProfileResetterDelegateTest,
-       TriggerResetAndSendFeedback) {
-  google_brand::BrandForTesting scoped_brand_for_testing(kTestBrandcode);
-
-  PrefService* prefs = profile()->GetPrefs();
-  DCHECK(prefs);
-  prefs->SetString(prefs::kHomePage, kTestHomepage);
-
-  testing::StrictMock<MockCallbackTarget> mock_target;
-  EXPECT_CALL(mock_target, Run());
-  EXPECT_CALL(*resetter_delegate(),
-              SendFeedback(testing::HasSubstr(kTestHomepage)));
-
-  resetter_delegate()->TriggerProfileSettingsReset(
-      true /*send_feedback*/, mock_target.CreateClosure());
-  ExpectAndServicePendingBrandcodedConfigFetch(false /*simulate_failure*/);
-  base::RunLoop().RunUntilIdle();
-}
-
-TEST_F(AutomaticProfileResetterDelegateTest, ShowAndDismissPrompt) {
-  resetter_delegate()->TriggerPrompt();
-  if (ProfileResetGlobalError::IsSupportedOnPlatform())
-    ExpectResetPromptState(true /*active*/);
-  else
-    ExpectResetPromptState(false /*active*/);
-  resetter_delegate()->DismissPrompt();
-  ExpectResetPromptState(false /*active*/);
-  resetter_delegate()->DismissPrompt();
-}
-
-}  // namespace
diff --git a/chrome/browser/profile_resetter/automatic_profile_resetter_factory.cc b/chrome/browser/profile_resetter/automatic_profile_resetter_factory.cc
deleted file mode 100644
index f025ce46..0000000
--- a/chrome/browser/profile_resetter/automatic_profile_resetter_factory.cc
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/profile_resetter/automatic_profile_resetter_factory.h"
-
-#include "base/memory/singleton.h"
-#include "base/prefs/pref_registry_simple.h"
-#include "chrome/browser/profile_resetter/automatic_profile_resetter.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/search_engines/template_url_service_factory.h"
-#include "chrome/browser/ui/global_error/global_error_service_factory.h"
-#include "chrome/common/pref_names.h"
-#include "components/keyed_service/content/browser_context_dependency_manager.h"
-#include "components/pref_registry/pref_registry_syncable.h"
-#include "content/public/browser/browser_context.h"
-
-// static
-AutomaticProfileResetter* AutomaticProfileResetterFactory::GetForBrowserContext(
-    content::BrowserContext* context) {
-  return static_cast<AutomaticProfileResetter*>(
-      GetInstance()->GetServiceForBrowserContext(context, true));
-}
-
-// static
-AutomaticProfileResetterFactory*
-AutomaticProfileResetterFactory::GetInstance() {
-  return base::Singleton<AutomaticProfileResetterFactory>::get();
-}
-
-// static
-void AutomaticProfileResetterFactory::RegisterPrefs(
-    PrefRegistrySimple* registry) {
-  registry->RegisterDictionaryPref(
-      prefs::kProfileResetPromptMementosInLocalState);
-}
-
-AutomaticProfileResetterFactory::AutomaticProfileResetterFactory()
-    : BrowserContextKeyedServiceFactory(
-          "AutomaticProfileResetter",
-          BrowserContextDependencyManager::GetInstance()) {
-  DependsOn(TemplateURLServiceFactory::GetInstance());
-  DependsOn(GlobalErrorServiceFactory::GetInstance());
-}
-
-AutomaticProfileResetterFactory::~AutomaticProfileResetterFactory() {}
-
-KeyedService* AutomaticProfileResetterFactory::BuildServiceInstanceFor(
-    content::BrowserContext* context) const {
-  Profile* profile = Profile::FromBrowserContext(context);
-  AutomaticProfileResetter* service = new AutomaticProfileResetter(profile);
-  service->Initialize();
-  service->Activate();
-  return service;
-}
-
-void AutomaticProfileResetterFactory::RegisterProfilePrefs(
-    user_prefs::PrefRegistrySyncable* registry) {
-  registry->RegisterStringPref(prefs::kProfileResetPromptMementoInProfilePrefs,
-                               "");
-}
-
-bool AutomaticProfileResetterFactory::
-    ServiceIsCreatedWithBrowserContext() const {
-  return true;
-}
-
-bool AutomaticProfileResetterFactory::ServiceIsNULLWhileTesting() const {
-  return true;
-}
diff --git a/chrome/browser/profile_resetter/automatic_profile_resetter_factory.h b/chrome/browser/profile_resetter/automatic_profile_resetter_factory.h
deleted file mode 100644
index bbf8012d..0000000
--- a/chrome/browser/profile_resetter/automatic_profile_resetter_factory.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_PROFILE_RESETTER_AUTOMATIC_PROFILE_RESETTER_FACTORY_H_
-#define CHROME_BROWSER_PROFILE_RESETTER_AUTOMATIC_PROFILE_RESETTER_FACTORY_H_
-
-#include "base/basictypes.h"
-#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
-
-namespace base {
-template <typename T>
-struct DefaultSingletonTraits;
-}  // namespace base
-
-class PrefRegistrySimple;
-
-namespace content {
-class BrowserContext;
-}
-
-namespace user_prefs {
-class PrefRegistrySyncable;
-}
-
-class AutomaticProfileResetter;
-
-class AutomaticProfileResetterFactory
-    : public BrowserContextKeyedServiceFactory {
- public:
-  static AutomaticProfileResetter* GetForBrowserContext(
-      content::BrowserContext* context);
-  static AutomaticProfileResetterFactory* GetInstance();
-
-  // Registers Local State preferences.
-  static void RegisterPrefs(PrefRegistrySimple* registry);
-
- private:
-  friend struct base::DefaultSingletonTraits<AutomaticProfileResetterFactory>;
-
-  AutomaticProfileResetterFactory();
-  ~AutomaticProfileResetterFactory() override;
-
-  // BrowserContextKeyedServiceFactory:
-  KeyedService* BuildServiceInstanceFor(
-      content::BrowserContext* context) const override;
-
-  // BrowserContextKeyedBaseFactory:
-  void RegisterProfilePrefs(
-      user_prefs::PrefRegistrySyncable* registry) override;
-  bool ServiceIsCreatedWithBrowserContext() const override;
-  bool ServiceIsNULLWhileTesting() const override;
-
-  DISALLOW_COPY_AND_ASSIGN(AutomaticProfileResetterFactory);
-};
-
-#endif  // CHROME_BROWSER_PROFILE_RESETTER_AUTOMATIC_PROFILE_RESETTER_FACTORY_H_
diff --git a/chrome/browser/profile_resetter/automatic_profile_resetter_mementos.cc b/chrome/browser/profile_resetter/automatic_profile_resetter_mementos.cc
deleted file mode 100644
index b4e9446..0000000
--- a/chrome/browser/profile_resetter/automatic_profile_resetter_mementos.cc
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/profile_resetter/automatic_profile_resetter_mementos.h"
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/files/file_path.h"
-#include "base/files/file_util.h"
-#include "base/logging.h"
-#include "base/prefs/pref_service.h"
-#include "base/prefs/scoped_user_pref_update.h"
-#include "base/values.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/common/chrome_constants.h"
-#include "chrome/common/pref_names.h"
-#include "content/public/browser/browser_thread.h"
-
-using base::DictionaryValue;
-
-
-// AutomaticProfileResetter::PreferenceHostedPromptMemento -------------------
-
-PreferenceHostedPromptMemento::PreferenceHostedPromptMemento(Profile* profile)
-    : profile_(profile) {}
-
-PreferenceHostedPromptMemento::~PreferenceHostedPromptMemento() {}
-
-std::string PreferenceHostedPromptMemento::ReadValue() const {
-  PrefService* prefs = profile_->GetPrefs();
-  DCHECK(prefs);
-  return prefs->GetString(prefs::kProfileResetPromptMementoInProfilePrefs);
-}
-
-void PreferenceHostedPromptMemento::StoreValue(const std::string& value) {
-  PrefService* prefs = profile_->GetPrefs();
-  DCHECK(prefs);
-  prefs->SetString(prefs::kProfileResetPromptMementoInProfilePrefs, value);
-}
-
-
-// AutomaticProfileResetter::LocalStateHostedPromptMemento -------------------
-
-LocalStateHostedPromptMemento::LocalStateHostedPromptMemento(Profile* profile)
-    : profile_(profile) {}
-
-LocalStateHostedPromptMemento::~LocalStateHostedPromptMemento() {}
-
-std::string LocalStateHostedPromptMemento::ReadValue() const {
-  PrefService* local_state = g_browser_process->local_state();
-  DCHECK(local_state);
-
-  const base::DictionaryValue* prompt_shown_dict = local_state->GetDictionary(
-      prefs::kProfileResetPromptMementosInLocalState);
-  std::string profile_key = GetProfileKey();
-  if (!prompt_shown_dict || profile_key.empty()) {
-    NOTREACHED();
-    return std::string();
-  }
-  std::string value;
-  return prompt_shown_dict->GetStringWithoutPathExpansion(profile_key, &value) ?
-      value : std::string();
-}
-
-void LocalStateHostedPromptMemento::StoreValue(const std::string& value) {
-  PrefService* local_state = g_browser_process->local_state();
-  DCHECK(local_state);
-
-  DictionaryPrefUpdate prompt_shown_dict_update(
-      local_state, prefs::kProfileResetPromptMementosInLocalState);
-  std::string profile_key = GetProfileKey();
-  if (profile_key.empty()) {
-    NOTREACHED();
-    return;
-  }
-  prompt_shown_dict_update.Get()->SetStringWithoutPathExpansion(profile_key,
-                                                                value);
-}
-
-std::string LocalStateHostedPromptMemento::GetProfileKey() const {
-  return profile_->GetPath().BaseName().MaybeAsASCII();
-}
-
-
-// AutomaticProfileResetter::FileHostedPromptMemento -------------------------
-
-FileHostedPromptMemento::FileHostedPromptMemento(Profile* profile)
-    : profile_(profile) {}
-
-FileHostedPromptMemento::~FileHostedPromptMemento() {}
-
-void FileHostedPromptMemento::ReadValue(
-    const ReadValueCallback& callback) const {
-  base::FilePath path = GetMementoFilePath();
-  content::BrowserThread::PostTaskAndReplyWithResult(
-      content::BrowserThread::FILE,
-      FROM_HERE,
-      base::Bind(&ReadValueOnFileThread, path),
-      callback);
-}
-
-void FileHostedPromptMemento::StoreValue(const std::string& value) {
-  base::FilePath path = GetMementoFilePath();
-  content::BrowserThread::PostTask(
-      content::BrowserThread::FILE,
-      FROM_HERE,
-      base::Bind(&StoreValueOnFileThread, path, value));
-}
-
-std::string FileHostedPromptMemento::ReadValueOnFileThread(
-    const base::FilePath& memento_file_path) {
-  std::string value;
-  base::ReadFileToString(memento_file_path, &value);
-  return value;
-}
-
-void FileHostedPromptMemento::StoreValueOnFileThread(
-    const base::FilePath& memento_file_path,
-    const std::string& value) {
-  int retval =
-      base::WriteFile(memento_file_path, value.c_str(), value.size());
-  DCHECK_EQ(retval, (int)value.size());
-}
-
-base::FilePath FileHostedPromptMemento::GetMementoFilePath() const {
-  return profile_->GetPath().Append(chrome::kResetPromptMementoFilename);
-}
diff --git a/chrome/browser/profile_resetter/automatic_profile_resetter_mementos.h b/chrome/browser/profile_resetter/automatic_profile_resetter_mementos.h
deleted file mode 100644
index 025ffb22..0000000
--- a/chrome/browser/profile_resetter/automatic_profile_resetter_mementos.h
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// The classes in this file are alternative implementations of the concept of a
-// "prompt memento", a token of some kind that gets stored when we show the
-// one-time profile reset prompt, and which then serves as a reminder that we
-// should not show the prompt again.
-//
-// In an ideal world, a single implementation would suffice, however, we expect
-// that third party software might accidentally interfere with some of these
-// methods. We need this redundancy because we want to make absolutely sure that
-// we do not annoy the user with the prompt multiple times.
-
-#ifndef CHROME_BROWSER_PROFILE_RESETTER_AUTOMATIC_PROFILE_RESETTER_MEMENTOS_H_
-#define CHROME_BROWSER_PROFILE_RESETTER_AUTOMATIC_PROFILE_RESETTER_MEMENTOS_H_
-
-#include <string>
-
-#include "base/basictypes.h"
-#include "base/callback.h"
-
-namespace base {
-class FilePath;
-}
-
-class Profile;
-
-// This class is a wrapper around the user preference that gets stored when we
-// show the one-time profile reset prompt, and which is kept as a reminder that
-// we should not show the prompt again.
-class PreferenceHostedPromptMemento {
- public:
-  explicit PreferenceHostedPromptMemento(Profile* profile);
-  ~PreferenceHostedPromptMemento();
-
-  std::string ReadValue() const;
-  void StoreValue(const std::string& value);
-
- private:
-  Profile* profile_;
-
-  DISALLOW_COPY_AND_ASSIGN(PreferenceHostedPromptMemento);
-};
-
-// This class is a wrapper around the Local State preference that gets stored
-// when we show the one-time profile reset prompt, and which is kept as a
-// reminder that we should not show the prompt again.
-class LocalStateHostedPromptMemento {
- public:
-  explicit LocalStateHostedPromptMemento(Profile* profile);
-  ~LocalStateHostedPromptMemento();
-
-  std::string ReadValue() const;
-  void StoreValue(const std::string& value);
-
- private:
-  // Returns the key that shall be used in the dictionary preference in Local
-  // State to uniquely identify this profile.
-  std::string GetProfileKey() const;
-
-  Profile* profile_;
-
-  DISALLOW_COPY_AND_ASSIGN(LocalStateHostedPromptMemento);
-};
-
-// This class manages a marker file that gets stored when we show the one-time
-// profile reset prompt, and which is kept as a reminder that we should not show
-// the prompt again.
-class FileHostedPromptMemento {
- public:
-  typedef base::Callback<void(const std::string&)> ReadValueCallback;
-
-  explicit FileHostedPromptMemento(Profile* profile);
-  ~FileHostedPromptMemento();
-
-  // Posts to the FILE thread to read the value, then returns the value to the
-  // calling thread. It is safe to destroy this object as soon as this method
-  // (synchronously) returns.
-  void ReadValue(const ReadValueCallback& callback) const;
-
-  // Asynchronously stores the value on the FILE thread. However, it is safe to
-  // destroy this object as soon as this method (synchronously) returns.
-  void StoreValue(const std::string& value);
-
- private:
-  static std::string ReadValueOnFileThread(
-      const base::FilePath& memento_file_path);
-  static void StoreValueOnFileThread(const base::FilePath& memento_file_path,
-                                     const std::string& value);
-
-  // Returns the path to the file that shall be used to store this kind of
-  // memento for this profile.
-  base::FilePath GetMementoFilePath() const;
-
-  Profile* profile_;
-
-  DISALLOW_COPY_AND_ASSIGN(FileHostedPromptMemento);
-};
-
-#endif  // CHROME_BROWSER_PROFILE_RESETTER_AUTOMATIC_PROFILE_RESETTER_MEMENTOS_H_
diff --git a/chrome/browser/profile_resetter/automatic_profile_resetter_unittest.cc b/chrome/browser/profile_resetter/automatic_profile_resetter_unittest.cc
deleted file mode 100644
index 046d7de7..0000000
--- a/chrome/browser/profile_resetter/automatic_profile_resetter_unittest.cc
+++ /dev/null
@@ -1,1377 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/profile_resetter/automatic_profile_resetter.h"
-
-#include <string>
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/metrics/field_trial.h"
-#include "base/prefs/pref_registry_simple.h"
-#include "base/prefs/testing_pref_service.h"
-#include "base/run_loop.h"
-#include "base/test/test_simple_task_runner.h"
-#include "base/threading/sequenced_worker_pool.h"
-#include "base/values.h"
-#include "chrome/browser/profile_resetter/automatic_profile_resetter_delegate.h"
-#include "chrome/browser/profile_resetter/automatic_profile_resetter_factory.h"
-#include "chrome/browser/profile_resetter/automatic_profile_resetter_mementos.h"
-#include "chrome/browser/profile_resetter/jtl_foundation.h"
-#include "chrome/browser/profile_resetter/jtl_instructions.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
-#include "chrome/test/base/testing_browser_process.h"
-#include "chrome/test/base/testing_profile.h"
-#include "components/pref_registry/pref_registry_syncable.h"
-#include "components/syncable_prefs/testing_pref_service_syncable.h"
-#include "components/variations/variations_associated_data.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/test/test_browser_thread_bundle.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using testing::_;
-
-namespace {
-
-const char kAutomaticProfileResetStudyName[] = "AutomaticProfileReset";
-const char kStudyDisabledGroupName[] = "Disabled";
-const char kStudyDryRunGroupName[] = "DryRun";
-const char kStudyEnabledGroupName[] = "Enabled";
-
-const char kTestHashSeed[] = "testing-hash-seed";
-const char kTestMementoValue[] = "01234567890123456789012345678901";
-const char kTestInvalidMementoValue[] = "12345678901234567890123456789012";
-
-const char kTestPreferencePath[] = "testing.preference";
-const char kTestPreferenceValue[] = "testing-preference-value";
-
-const char kSearchURLAttributeKey[] = "search_url";
-const char kTestSearchURL[] = "http://example.com/search?q={searchTerms}";
-const char kTestSearchURL2[] = "http://google.com/?q={searchTerms}";
-
-const char kTestModuleDigest[] = "01234567890123456789012345678901";
-const char kTestModuleDigest2[] = "12345678901234567890123456789012";
-
-// Helpers ------------------------------------------------------------------
-
-// A testing version of the AutomaticProfileResetter that differs from the real
-// one only in that it has its statistics reporting mocked out for verification.
-class AutomaticProfileResetterUnderTest : public AutomaticProfileResetter {
- public:
-  explicit AutomaticProfileResetterUnderTest(Profile* profile)
-      : AutomaticProfileResetter(profile) {}
-  ~AutomaticProfileResetterUnderTest() override {}
-
-  MOCK_METHOD2(ReportStatistics, void(uint32, uint32));
-  MOCK_METHOD1(ReportPromptResult,
-      void(AutomaticProfileResetter::PromptResult));
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(AutomaticProfileResetterUnderTest);
-};
-
-class MockProfileResetterDelegate : public AutomaticProfileResetterDelegate {
- public:
-  MockProfileResetterDelegate()
-      : emulated_is_default_search_provider_managed_(false) {}
-  ~MockProfileResetterDelegate() override {}
-
-  MOCK_METHOD0(EnumerateLoadedModulesIfNeeded, void());
-  MOCK_CONST_METHOD1(RequestCallbackWhenLoadedModulesAreEnumerated,
-                     void(const base::Closure&));
-
-  MOCK_METHOD0(LoadTemplateURLServiceIfNeeded, void());
-  MOCK_CONST_METHOD1(RequestCallbackWhenTemplateURLServiceIsLoaded,
-                     void(const base::Closure&));
-
-  MOCK_METHOD0(FetchBrandcodedDefaultSettingsIfNeeded, void());
-  MOCK_CONST_METHOD1(RequestCallbackWhenBrandcodedDefaultsAreFetched,
-                     void(const base::Closure&));
-
-  MOCK_CONST_METHOD0(OnGetLoadedModuleNameDigestsCalled, void());
-  MOCK_CONST_METHOD0(OnGetDefaultSearchProviderDetailsCalled, void());
-  MOCK_CONST_METHOD0(OnIsDefaultSearchProviderManagedCalled, void());
-  MOCK_CONST_METHOD0(OnGetPrepopulatedSearchProvidersDetailsCalled, void());
-
-  MOCK_METHOD0(TriggerPrompt, bool());
-  MOCK_METHOD2(TriggerProfileSettingsReset, void(bool, const base::Closure&));
-  MOCK_METHOD0(DismissPrompt, void());
-
-  scoped_ptr<base::ListValue> GetLoadedModuleNameDigests() const override {
-    OnGetLoadedModuleNameDigestsCalled();
-    return scoped_ptr<base::ListValue>(
-        emulated_loaded_module_digests_.DeepCopy());
-  }
-
-  scoped_ptr<base::DictionaryValue>
-      GetDefaultSearchProviderDetails() const override {
-    OnGetDefaultSearchProviderDetailsCalled();
-    return scoped_ptr<base::DictionaryValue>(
-        emulated_default_search_provider_details_.DeepCopy());
-  }
-
-  bool IsDefaultSearchProviderManaged() const override {
-    OnIsDefaultSearchProviderManagedCalled();
-    return emulated_is_default_search_provider_managed_;
-  }
-
-  scoped_ptr<base::ListValue>
-      GetPrepopulatedSearchProvidersDetails() const override {
-    OnGetPrepopulatedSearchProvidersDetailsCalled();
-    return scoped_ptr<base::ListValue>(
-        emulated_search_providers_details_.DeepCopy());
-  }
-
-  static void ClosureInvoker(const base::Closure& closure) { closure.Run(); }
-
-  void ExpectCallsToDependenciesSetUpMethods() {
-    EXPECT_CALL(*this, EnumerateLoadedModulesIfNeeded());
-    EXPECT_CALL(*this, LoadTemplateURLServiceIfNeeded());
-    EXPECT_CALL(*this, RequestCallbackWhenLoadedModulesAreEnumerated(_))
-        .WillOnce(testing::Invoke(ClosureInvoker));
-    EXPECT_CALL(*this, RequestCallbackWhenTemplateURLServiceIsLoaded(_))
-        .WillOnce(testing::Invoke(ClosureInvoker));
-  }
-
-  void ExpectCallsToGetterMethods() {
-    EXPECT_CALL(*this, OnGetLoadedModuleNameDigestsCalled());
-    EXPECT_CALL(*this, OnGetDefaultSearchProviderDetailsCalled());
-    EXPECT_CALL(*this, OnIsDefaultSearchProviderManagedCalled());
-    EXPECT_CALL(*this, OnGetPrepopulatedSearchProvidersDetailsCalled());
-  }
-
-  void ExpectCallToShowPrompt() {
-    EXPECT_CALL(*this, TriggerPrompt()).WillOnce(testing::Return(true));
-    EXPECT_CALL(*this, FetchBrandcodedDefaultSettingsIfNeeded());
-  }
-
-  void ExpectCallToTriggerReset(bool send_feedback) {
-    EXPECT_CALL(*this, TriggerProfileSettingsReset(send_feedback, _))
-        .WillOnce(testing::SaveArg<1>(&reset_completion_));
-  }
-
-  base::DictionaryValue& emulated_default_search_provider_details() {
-    return emulated_default_search_provider_details_;
-  }
-
-  base::ListValue& emulated_search_providers_details() {
-    return emulated_search_providers_details_;
-  }
-
-  base::ListValue& emulated_loaded_module_digests() {
-    return emulated_loaded_module_digests_;
-  }
-
-  void set_emulated_is_default_search_provider_managed(bool value) {
-    emulated_is_default_search_provider_managed_ = value;
-  }
-
-  void EmulateProfileResetCompleted() {
-    reset_completion_.Run();
-  }
-
- private:
-  base::DictionaryValue emulated_default_search_provider_details_;
-  base::ListValue emulated_search_providers_details_;
-  base::ListValue emulated_loaded_module_digests_;
-  bool emulated_is_default_search_provider_managed_;
-  base::Closure reset_completion_;
-
-  DISALLOW_COPY_AND_ASSIGN(MockProfileResetterDelegate);
-};
-
-class FileHostedPromptMementoSynchronous : protected FileHostedPromptMemento {
- public:
-  explicit FileHostedPromptMementoSynchronous(Profile* profile)
-      : FileHostedPromptMemento(profile) {}
-
-  std::string ReadValue() const {
-    std::string result;
-    FileHostedPromptMemento::ReadValue(base::Bind(&AssignArgumentTo, &result));
-    base::RunLoop().RunUntilIdle();
-    return result;
-  }
-
-  void StoreValue(const std::string& value) {
-    FileHostedPromptMemento::StoreValue(value);
-    base::RunLoop().RunUntilIdle();
-  }
-
- private:
-  static void AssignArgumentTo(std::string* target, const std::string& value) {
-    *target = value;
-  }
-
-  DISALLOW_COPY_AND_ASSIGN(FileHostedPromptMementoSynchronous);
-};
-
-std::string GetHash(const std::string& input) {
-  return jtl_foundation::Hasher(kTestHashSeed).GetHash(input);
-}
-
-// Encodes a Boolean argument value into JTL bytecode.
-std::string EncodeBool(bool value) { return value ? VALUE_TRUE : VALUE_FALSE; }
-
-// Constructs a simple evaluation program to test that basic input/output works
-// well. It will emulate a scenario in which the reset criteria are satisfied as
-// prescribed by |emulate_satisfied_criterion_{1|2}|, and the reset is triggered
-// when either of them is true. The bits in the combined status mask will be set
-// according to whether or not the memento values received in the input were as
-// expected.
-//
-// More specifically, the output of the program will be as follows:
-// {
-//   "satisfied_criteria_mask_bit1": emulate_satisfied_criterion_1,
-//   "satisfied_criteria_mask_bit2": emulate_satisfied_criterion_2,
-//   "combined_status_mask_bit1":
-//      (emulate_satisfied_criterion_1 || emulate_satisfied_criterion_2),
-//   "combined_status_mask_bit2":
-//      (input["memento_value_in_prefs"] == kTestMementoValue),
-//   "combined_status_mask_bit3":
-//      (input["memento_value_in_local_state"] == kTestMementoValue),
-//   "combined_status_mask_bit4":
-//      (input["memento_value_in_file"] == kTestMementoValue),
-//   "should_prompt":
-//      (emulate_satisfied_criterion_1 || emulate_satisfied_criterion_2),
-//   "had_prompted_already": <OR-combination of above three>,
-//   "memento_value_in_prefs": kTestMementoValue,
-//   "memento_value_in_local_state": kTestMementoValue,
-//   "memento_value_in_file": kTestMementoValue
-// }
-std::string ConstructProgram(bool emulate_satisfied_criterion_1,
-                             bool emulate_satisfied_criterion_2) {
-  std::string bytecode;
-  bytecode += OP_STORE_BOOL(GetHash("satisfied_criteria_mask_bit1"),
-                            EncodeBool(emulate_satisfied_criterion_1));
-  bytecode += OP_END_OF_SENTENCE;
-  bytecode += OP_STORE_BOOL(GetHash("satisfied_criteria_mask_bit2"),
-                            EncodeBool(emulate_satisfied_criterion_2));
-  bytecode += OP_END_OF_SENTENCE;
-  bytecode += OP_STORE_BOOL(GetHash("should_prompt"),
-                            EncodeBool(emulate_satisfied_criterion_1 ||
-                                       emulate_satisfied_criterion_2));
-  bytecode += OP_END_OF_SENTENCE;
-  bytecode += OP_STORE_BOOL(GetHash("combined_status_mask_bit1"),
-                            EncodeBool(emulate_satisfied_criterion_1 ||
-                                       emulate_satisfied_criterion_2));
-  bytecode += OP_END_OF_SENTENCE;
-  bytecode += OP_NAVIGATE(GetHash("memento_value_in_prefs"));
-  bytecode += OP_COMPARE_NODE_HASH(GetHash(kTestMementoValue));
-  bytecode += OP_STORE_BOOL(GetHash("combined_status_mask_bit2"), VALUE_TRUE);
-  bytecode += OP_STORE_BOOL(GetHash("had_prompted_already"), VALUE_TRUE);
-  bytecode += OP_END_OF_SENTENCE;
-  bytecode += OP_NAVIGATE(GetHash("memento_value_in_local_state"));
-  bytecode += OP_COMPARE_NODE_HASH(GetHash(kTestMementoValue));
-  bytecode += OP_STORE_BOOL(GetHash("combined_status_mask_bit3"), VALUE_TRUE);
-  bytecode += OP_STORE_BOOL(GetHash("had_prompted_already"), VALUE_TRUE);
-  bytecode += OP_END_OF_SENTENCE;
-  bytecode += OP_NAVIGATE(GetHash("memento_value_in_file"));
-  bytecode += OP_COMPARE_NODE_HASH(GetHash(kTestMementoValue));
-  bytecode += OP_STORE_BOOL(GetHash("combined_status_mask_bit4"), VALUE_TRUE);
-  bytecode += OP_STORE_BOOL(GetHash("had_prompted_already"), VALUE_TRUE);
-  bytecode += OP_END_OF_SENTENCE;
-  bytecode += OP_STORE_HASH(GetHash("memento_value_in_prefs"),
-                            kTestMementoValue);
-  bytecode += OP_END_OF_SENTENCE;
-  bytecode += OP_STORE_HASH(GetHash("memento_value_in_local_state"),
-                            kTestMementoValue);
-  bytecode += OP_END_OF_SENTENCE;
-  bytecode += OP_STORE_HASH(GetHash("memento_value_in_file"),
-                            kTestMementoValue);
-  bytecode += OP_END_OF_SENTENCE;
-  return bytecode;
-}
-
-// Constructs another evaluation program to specifically test that bits of the
-// "satisfied_criteria_mask" are correctly assigned, and so is "should_prompt";
-// and that reset is triggered iff the latter is true, regardless of the bits
-// in the mask (so as to allow for a non-disjunctive compound criterion).
-//
-// More specifically, the output of the program will be as follows:
-// {
-//   "satisfied_criteria_mask_bitN": emulate_satisfied_odd_criteria,
-//   "satisfied_criteria_mask_bitM": emulate_satisfied_even_criteria,
-//   "combined_status_mask_bit1": emulate_should_prompt,
-//   "should_prompt": emulate_should_prompt,
-//   "memento_value_in_prefs": kTestMementoValue,
-//   "memento_value_in_local_state": kTestMementoValue,
-//   "memento_value_in_file": kTestMementoValue
-// }
-// ... such that N is {1,3,5} and M is {2,4}.
-std::string ConstructProgramToExerciseCriteria(
-    bool emulate_should_prompt,
-    bool emulate_satisfied_odd_criteria,
-    bool emulate_satisfied_even_criteria) {
-  std::string bytecode;
-  bytecode += OP_STORE_BOOL(GetHash("satisfied_criteria_mask_bit1"),
-                            EncodeBool(emulate_satisfied_odd_criteria));
-  bytecode += OP_END_OF_SENTENCE;
-  bytecode += OP_STORE_BOOL(GetHash("satisfied_criteria_mask_bit3"),
-                            EncodeBool(emulate_satisfied_odd_criteria));
-  bytecode += OP_END_OF_SENTENCE;
-  bytecode += OP_STORE_BOOL(GetHash("satisfied_criteria_mask_bit5"),
-                            EncodeBool(emulate_satisfied_odd_criteria));
-  bytecode += OP_END_OF_SENTENCE;
-  bytecode += OP_STORE_BOOL(GetHash("satisfied_criteria_mask_bit2"),
-                            EncodeBool(emulate_satisfied_even_criteria));
-  bytecode += OP_END_OF_SENTENCE;
-  bytecode += OP_STORE_BOOL(GetHash("satisfied_criteria_mask_bit4"),
-                            EncodeBool(emulate_satisfied_even_criteria));
-  bytecode += OP_END_OF_SENTENCE;
-  bytecode += OP_STORE_BOOL(GetHash("should_prompt"),
-                            EncodeBool(emulate_should_prompt));
-  bytecode += OP_END_OF_SENTENCE;
-  bytecode += OP_STORE_BOOL(GetHash("combined_status_mask_bit1"),
-                            EncodeBool(emulate_should_prompt));
-  bytecode += OP_END_OF_SENTENCE;
-  bytecode += OP_STORE_HASH(GetHash("memento_value_in_prefs"),
-                            kTestMementoValue);
-  bytecode += OP_END_OF_SENTENCE;
-  bytecode += OP_STORE_HASH(GetHash("memento_value_in_local_state"),
-                            kTestMementoValue);
-  bytecode += OP_END_OF_SENTENCE;
-  bytecode += OP_STORE_HASH(GetHash("memento_value_in_file"),
-                            kTestMementoValue);
-  bytecode += OP_END_OF_SENTENCE;
-  return bytecode;
-}
-
-// Constructs another evaluation program to specifically test that local state
-// and user preference values are included in the input as expected. We will
-// re-purpose the output bitmasks to channel out information about the outcome
-// of the checks.
-//
-// More specifically, the output of the program will be as follows:
-// {
-//   "combined_status_mask_bit1":
-//       (input["preferences.testing.preference"] == kTestPreferenceValue)
-//   "combined_status_mask_bit2":
-//       (input["local_state.testing.preference"] == kTestPreferenceValue)
-//   "combined_status_mask_bit3": input["preferences_iuc.testing.preference"]
-//   "combined_status_mask_bit4": input["local_state_iuc.testing.preference"]
-// }
-std::string ConstructProgramToCheckPreferences() {
-  std::string bytecode;
-  bytecode += OP_NAVIGATE(GetHash("preferences"));
-  bytecode += OP_NAVIGATE(GetHash("testing"));
-  bytecode += OP_NAVIGATE(GetHash("preference"));
-  bytecode += OP_COMPARE_NODE_HASH(GetHash(kTestPreferenceValue));
-  bytecode += OP_STORE_BOOL(GetHash("combined_status_mask_bit1"),
-                            EncodeBool(true));
-  bytecode += OP_END_OF_SENTENCE;
-  bytecode += OP_NAVIGATE(GetHash("local_state"));
-  bytecode += OP_NAVIGATE(GetHash("testing"));
-  bytecode += OP_NAVIGATE(GetHash("preference"));
-  bytecode += OP_COMPARE_NODE_HASH(GetHash(kTestPreferenceValue));
-  bytecode += OP_STORE_BOOL(GetHash("combined_status_mask_bit2"),
-                            EncodeBool(true));
-  bytecode += OP_END_OF_SENTENCE;
-  bytecode += OP_NAVIGATE(GetHash("preferences_iuc"));
-  bytecode += OP_NAVIGATE(GetHash("testing"));
-  bytecode += OP_NAVIGATE(GetHash("preference"));
-  bytecode += OP_COMPARE_NODE_BOOL(EncodeBool(true));
-  bytecode += OP_STORE_BOOL(GetHash("combined_status_mask_bit3"),
-                            EncodeBool(true));
-  bytecode += OP_END_OF_SENTENCE;
-  bytecode += OP_NAVIGATE(GetHash("local_state_iuc"));
-  bytecode += OP_NAVIGATE(GetHash("testing"));
-  bytecode += OP_NAVIGATE(GetHash("preference"));
-  bytecode += OP_COMPARE_NODE_BOOL(EncodeBool(true));
-  bytecode += OP_STORE_BOOL(GetHash("combined_status_mask_bit4"),
-                            EncodeBool(true));
-  bytecode += OP_END_OF_SENTENCE;
-  return bytecode;
-}
-
-// Legend for the bitmask returned by the above program.
-enum CombinedStatusMaskLegendForCheckingPreferences {
-  HAS_EXPECTED_USER_PREFERENCE = 1 << 0,
-  HAS_EXPECTED_LOCAL_STATE_PREFERENCE = 1 << 1,
-  USER_PREFERENCE_IS_USER_CONTROLLED = 1 << 2,
-  LOCAL_STATE_IS_USER_CONTROLLED = 1 << 3,
-};
-
-// Constructs yet another evaluation program to specifically test that default
-// and pre-populated search engines are included in the input as expected. We
-// will re-purpose the output bitmasks to channel out information about the
-// outcome of the checks.
-//
-// More specifically, the output of the program will be as follows:
-// {
-//   "combined_status_mask_bit1":
-//       (input["default_search_provider.search_url"] == kTestSearchURL)
-//   "combined_status_mask_bit2": input["default_search_provider_iuc"]
-//   "combined_status_mask_bit3":
-//       (input["search_providers.*.search_url"] == kTestSearchURL)
-//   "combined_status_mask_bit4":
-//       (input["search_providers.*.search_url"] == kTestSearchURL2)
-// }
-std::string ConstructProgramToCheckSearchEngines() {
-  std::string bytecode;
-  bytecode += OP_NAVIGATE(GetHash("default_search_provider"));
-  bytecode += OP_NAVIGATE(GetHash("search_url"));
-  bytecode += OP_COMPARE_NODE_HASH(GetHash(kTestSearchURL));
-  bytecode += OP_STORE_BOOL(GetHash("combined_status_mask_bit1"),
-                            EncodeBool(true));
-  bytecode += OP_END_OF_SENTENCE;
-  bytecode += OP_NAVIGATE(GetHash("default_search_provider_iuc"));
-  bytecode += OP_COMPARE_NODE_BOOL(EncodeBool(true));
-  bytecode += OP_STORE_BOOL(GetHash("combined_status_mask_bit2"),
-                            EncodeBool(true));
-  bytecode += OP_END_OF_SENTENCE;
-  bytecode += OP_NAVIGATE(GetHash("search_providers"));
-  bytecode += OP_NAVIGATE_ANY;
-  bytecode += OP_NAVIGATE(GetHash("search_url"));
-  bytecode += OP_COMPARE_NODE_HASH(GetHash(kTestSearchURL));
-  bytecode += OP_STORE_BOOL(GetHash("combined_status_mask_bit3"),
-                            EncodeBool(true));
-  bytecode += OP_END_OF_SENTENCE;
-  bytecode += OP_NAVIGATE(GetHash("search_providers"));
-  bytecode += OP_NAVIGATE_ANY;
-  bytecode += OP_NAVIGATE(GetHash("search_url"));
-  bytecode += OP_COMPARE_NODE_HASH(GetHash(kTestSearchURL2));
-  bytecode += OP_STORE_BOOL(GetHash("combined_status_mask_bit4"),
-                            EncodeBool(true));
-  bytecode += OP_END_OF_SENTENCE;
-  return bytecode;
-}
-
-// Legend for the bitmask returned by the above program.
-enum CombinedStatusMaskLegendForCheckingSearchEngines {
-  HAS_EXPECTED_DEFAULT_SEARCH_PROVIDER = 1 << 0,
-  DEFAULT_SEARCH_PROVIDER_IS_USER_CONTROLLED = 1 << 1,
-  HAS_EXPECTED_PREPOPULATED_SEARCH_PROVIDER_1 = 1 << 2,
-  HAS_EXPECTED_PREPOPULATED_SEARCH_PROVIDER_2 = 1 << 3,
-};
-
-// Constructs yet another evaluation program to specifically test that loaded
-// module digests are included in the input as expected. We will re-purpose the
-// output bitmasks to channel out information about the outcome of the checks.
-//
-// More specifically, the output of the program will be as follows:
-// {
-//   "combined_status_mask_bit1":
-//       (input["loaded_modules.*"] == kTestModuleDigest)
-//   "combined_status_mask_bit2":
-//       (input["loaded_modules.*"] == kTestModuleDigest2)
-// }
-std::string ConstructProgramToCheckLoadedModuleDigests() {
-  std::string bytecode;
-  bytecode += OP_NAVIGATE(GetHash("loaded_modules"));
-  bytecode += OP_NAVIGATE_ANY;
-  bytecode += OP_COMPARE_NODE_HASH(GetHash(kTestModuleDigest));
-  bytecode += OP_STORE_BOOL(GetHash("combined_status_mask_bit1"),
-                            EncodeBool(true));
-  bytecode += OP_END_OF_SENTENCE;
-  bytecode += OP_NAVIGATE(GetHash("loaded_modules"));
-  bytecode += OP_NAVIGATE_ANY;
-  bytecode += OP_COMPARE_NODE_HASH(GetHash(kTestModuleDigest2));
-  bytecode += OP_STORE_BOOL(GetHash("combined_status_mask_bit2"),
-                            EncodeBool(true));
-  bytecode += OP_END_OF_SENTENCE;
-  return bytecode;
-}
-
-// Legend for the bitmask returned by the above program.
-enum CombinedStatusMaskLegendForCheckingLoadedModules {
-  HAS_EXPECTED_MODULE_DIGEST_1 = 1 << 0,
-  HAS_EXPECTED_MODULE_DIGEST_2 = 1 << 1,
-};
-
-// Test fixtures -------------------------------------------------------------
-
-class AutomaticProfileResetterTestBase : public testing::Test {
- protected:
-  explicit AutomaticProfileResetterTestBase(
-      const std::string& experiment_group_name)
-      : waiting_task_runner_(new base::TestSimpleTaskRunner),
-        local_state_(TestingBrowserProcess::GetGlobal()),
-        profile_(new TestingProfile()),
-        field_trials_(new base::FieldTrialList(NULL)),
-        memento_in_prefs_(new PreferenceHostedPromptMemento(profile())),
-        memento_in_local_state_(new LocalStateHostedPromptMemento(profile())),
-        memento_in_file_(new FileHostedPromptMementoSynchronous(profile())),
-        experiment_group_name_(experiment_group_name),
-        inject_data_through_variation_params_(false),
-        mock_delegate_(NULL) {
-    // Make sure the factory is not optimized away, so whatever preferences it
-    // wants to register will actually get registered.
-    AutomaticProfileResetterFactory::GetInstance();
-
-    // Register some additional local state preferences for testing purposes.
-    PrefRegistrySimple* local_state_registry = local_state_.Get()->registry();
-    DCHECK(local_state_registry);
-    local_state_registry->RegisterStringPref(kTestPreferencePath, "");
-
-    // Register some additional user preferences for testing purposes.
-    user_prefs::PrefRegistrySyncable* user_prefs_registry =
-        profile_->GetTestingPrefService()->registry();
-    DCHECK(user_prefs_registry);
-    user_prefs_registry->RegisterStringPref(kTestPreferencePath, std::string());
-  }
-
-  void SetUp() override {
-    variations::testing::ClearAllVariationParams();
-    base::FieldTrialList::CreateFieldTrial(kAutomaticProfileResetStudyName,
-                                           experiment_group_name_);
-    resetter_.reset(
-        new testing::StrictMock<AutomaticProfileResetterUnderTest>(profile()));
-    mock_delegate_owned_.reset(
-        new testing::StrictMock<MockProfileResetterDelegate>());
-    mock_delegate_ = mock_delegate_owned_.get();
-
-    ExpectAllMementoValuesEqualTo(std::string());
-  }
-
-  void SetTestingHashSeed(const std::string& hash_seed) {
-    testing_hash_seed_ = hash_seed;
-  }
-
-  void SetTestingProgram(const std::string& source_code) {
-    testing_program_ = source_code;
-  }
-
-  void AllowInjectingTestDataThroughVariationParams(bool value) {
-    inject_data_through_variation_params_ = value;
-  }
-
-  void ExpectAllMementoValuesEqualTo(const std::string& value) {
-    EXPECT_EQ(value, memento_in_prefs_->ReadValue());
-    EXPECT_EQ(value, memento_in_local_state_->ReadValue());
-    EXPECT_EQ(value, memento_in_file_->ReadValue());
-  }
-
-  void UnleashResetterAndWait() {
-    if (inject_data_through_variation_params_) {
-      std::map<std::string, std::string> variation_params;
-      variation_params["program"] = testing_program_;
-      variation_params["hash_seed"] = testing_hash_seed_;
-      ASSERT_TRUE(variations::AssociateVariationParams(
-          kAutomaticProfileResetStudyName,
-          experiment_group_name_,
-          variation_params));
-    }
-    resetter_->Initialize();
-    resetter_->SetDelegateForTesting(mock_delegate_owned_.Pass());
-    resetter_->SetTaskRunnerForWaitingForTesting(waiting_task_runner_);
-    if (!inject_data_through_variation_params_) {
-      resetter_->SetProgramForTesting(testing_program_);
-      resetter_->SetHashSeedForTesting(testing_hash_seed_);
-    }
-    resetter_->Activate();
-
-    if (waiting_task_runner_->HasPendingTask()) {
-      ASSERT_EQ(base::TimeDelta::FromSeconds(55),
-                waiting_task_runner_->NextPendingTaskDelay());
-      waiting_task_runner_->RunPendingTasks();
-    }
-    base::RunLoop().RunUntilIdle();
-    content::BrowserThread::GetBlockingPool()->FlushForTesting();
-    base::RunLoop().RunUntilIdle();
-  }
-
-  // Goes through an evaluation flow such that the reset criteria are satisfied.
-  // Used to reduce boilerplate for tests that need to verify behavior during
-  // the reset prompt flow.
-  void OrchestrateThroughEvaluationFlow() {
-    SetTestingProgram(ConstructProgram(true, true));
-    SetTestingHashSeed(kTestHashSeed);
-
-    mock_delegate().ExpectCallsToDependenciesSetUpMethods();
-    mock_delegate().ExpectCallsToGetterMethods();
-    mock_delegate().ExpectCallToShowPrompt();
-    EXPECT_CALL(resetter(), ReportStatistics(0x03u, 0x01u));
-
-    UnleashResetterAndWait();
-
-    EXPECT_TRUE(resetter().ShouldShowResetBanner());
-    testing::Mock::VerifyAndClearExpectations(&resetter());
-    testing::Mock::VerifyAndClearExpectations(&mock_delegate());
-  }
-
-  // Explicitly shut down the service to double-check that nothing explodes, but
-  // first, verify expectations to make sure the service makes no more calls to
-  // any mocked functions during or after shutdown.
-  void VerifyExpectationsThenShutdownResetter() {
-    testing::Mock::VerifyAndClearExpectations(&resetter());
-    testing::Mock::VerifyAndClearExpectations(&mock_delegate());
-
-    resetter_->Shutdown();
-    resetter_.reset();
-  }
-
-  TestingProfile* profile() { return profile_.get(); }
-  TestingPrefServiceSimple* local_state() { return local_state_.Get(); }
-
-  PreferenceHostedPromptMemento& memento_in_prefs() {
-    return *memento_in_prefs_;
-  }
-
-  LocalStateHostedPromptMemento& memento_in_local_state() {
-    return *memento_in_local_state_;
-  }
-
-  FileHostedPromptMementoSynchronous& memento_in_file() {
-    return *memento_in_file_;
-  }
-
-  MockProfileResetterDelegate& mock_delegate() { return *mock_delegate_; }
-  AutomaticProfileResetterUnderTest& resetter() { return *resetter_; }
-
- private:
-  content::TestBrowserThreadBundle thread_bundle_;
-  scoped_refptr<base::TestSimpleTaskRunner> waiting_task_runner_;
-  ScopedTestingLocalState local_state_;
-  scoped_ptr<TestingProfile> profile_;
-  scoped_ptr<base::FieldTrialList> field_trials_;
-  scoped_ptr<PreferenceHostedPromptMemento> memento_in_prefs_;
-  scoped_ptr<LocalStateHostedPromptMemento> memento_in_local_state_;
-  scoped_ptr<FileHostedPromptMementoSynchronous> memento_in_file_;
-
-  std::string experiment_group_name_;
-  std::string testing_program_;
-  std::string testing_hash_seed_;
-  bool inject_data_through_variation_params_;
-
-  scoped_ptr<AutomaticProfileResetterUnderTest> resetter_;
-  scoped_ptr<MockProfileResetterDelegate> mock_delegate_owned_;
-  MockProfileResetterDelegate* mock_delegate_;
-
-  DISALLOW_COPY_AND_ASSIGN(AutomaticProfileResetterTestBase);
-};
-
-class AutomaticProfileResetterTest : public AutomaticProfileResetterTestBase {
- protected:
-  AutomaticProfileResetterTest()
-      : AutomaticProfileResetterTestBase(kStudyEnabledGroupName) {}
-};
-
-class AutomaticProfileResetterTestDryRun
-    : public AutomaticProfileResetterTestBase {
- protected:
-  AutomaticProfileResetterTestDryRun()
-      : AutomaticProfileResetterTestBase(kStudyDryRunGroupName) {}
-};
-
-class AutomaticProfileResetterTestDisabled
-    : public AutomaticProfileResetterTestBase {
- protected:
-  AutomaticProfileResetterTestDisabled()
-      : AutomaticProfileResetterTestBase(kStudyDisabledGroupName) {}
-};
-
-// Tests ---------------------------------------------------------------------
-
-TEST_F(AutomaticProfileResetterTestDisabled, NothingIsDoneWhenDisabled) {
-  SetTestingProgram(ConstructProgram(true, true));
-  SetTestingHashSeed(kTestHashSeed);
-
-  // No calls are expected to the delegate.
-
-  UnleashResetterAndWait();
-
-  EXPECT_FALSE(resetter().ShouldShowResetBanner());
-  VerifyExpectationsThenShutdownResetter();
-
-  ExpectAllMementoValuesEqualTo(std::string());
-}
-
-TEST_F(AutomaticProfileResetterTestDryRun, CriteriaNotSatisfied) {
-  SetTestingProgram(ConstructProgramToExerciseCriteria(false, true, true));
-  SetTestingHashSeed(kTestHashSeed);
-
-  mock_delegate().ExpectCallsToDependenciesSetUpMethods();
-  mock_delegate().ExpectCallsToGetterMethods();
-  EXPECT_CALL(resetter(), ReportStatistics(0x1fu, 0x00u));
-
-  UnleashResetterAndWait();
-
-  EXPECT_FALSE(resetter().ShouldShowResetBanner());
-  VerifyExpectationsThenShutdownResetter();
-
-  ExpectAllMementoValuesEqualTo(std::string());
-}
-
-TEST_F(AutomaticProfileResetterTestDryRun, OddCriteriaSatisfied) {
-  SetTestingProgram(ConstructProgramToExerciseCriteria(true, true, false));
-  SetTestingHashSeed(kTestHashSeed);
-
-  mock_delegate().ExpectCallsToDependenciesSetUpMethods();
-  mock_delegate().ExpectCallsToGetterMethods();
-  EXPECT_CALL(resetter(), ReportStatistics(0x15u, 0x01u));
-  EXPECT_CALL(resetter(), ReportPromptResult(
-      AutomaticProfileResetter::PROMPT_NOT_TRIGGERED));
-
-  UnleashResetterAndWait();
-
-  ExpectAllMementoValuesEqualTo(kTestMementoValue);
-  EXPECT_FALSE(resetter().ShouldShowResetBanner());
-  VerifyExpectationsThenShutdownResetter();
-}
-
-TEST_F(AutomaticProfileResetterTestDryRun, EvenCriteriaSatisfied) {
-  SetTestingProgram(ConstructProgramToExerciseCriteria(true, false, true));
-  SetTestingHashSeed(kTestHashSeed);
-
-  mock_delegate().ExpectCallsToDependenciesSetUpMethods();
-  mock_delegate().ExpectCallsToGetterMethods();
-  EXPECT_CALL(resetter(), ReportStatistics(0x0au, 0x01u));
-  EXPECT_CALL(resetter(), ReportPromptResult(
-      AutomaticProfileResetter::PROMPT_NOT_TRIGGERED));
-
-  UnleashResetterAndWait();
-
-  ExpectAllMementoValuesEqualTo(kTestMementoValue);
-  EXPECT_FALSE(resetter().ShouldShowResetBanner());
-  VerifyExpectationsThenShutdownResetter();
-}
-
-#if defined(GOOGLE_CHROME_BUILD)
-TEST_F(AutomaticProfileResetterTestDryRun, ProgramSetThroughVariationParams) {
-  SetTestingProgram(ConstructProgram(true, true));
-  SetTestingHashSeed(kTestHashSeed);
-  AllowInjectingTestDataThroughVariationParams(true);
-
-  mock_delegate().ExpectCallsToDependenciesSetUpMethods();
-  mock_delegate().ExpectCallsToGetterMethods();
-  EXPECT_CALL(resetter(), ReportStatistics(0x03u, 0x01u));
-  EXPECT_CALL(resetter(), ReportPromptResult(
-      AutomaticProfileResetter::PROMPT_NOT_TRIGGERED));
-
-  UnleashResetterAndWait();
-
-  ExpectAllMementoValuesEqualTo(kTestMementoValue);
-  EXPECT_FALSE(resetter().ShouldShowResetBanner());
-  VerifyExpectationsThenShutdownResetter();
-}
-#endif
-
-TEST_F(AutomaticProfileResetterTestDryRun,
-       ConditionsSatisfiedAndInvalidMementos) {
-  memento_in_prefs().StoreValue(kTestInvalidMementoValue);
-  memento_in_local_state().StoreValue(kTestInvalidMementoValue);
-  memento_in_file().StoreValue(kTestInvalidMementoValue);
-
-  SetTestingProgram(ConstructProgram(true, true));
-  SetTestingHashSeed(kTestHashSeed);
-
-  mock_delegate().ExpectCallsToDependenciesSetUpMethods();
-  mock_delegate().ExpectCallsToGetterMethods();
-  EXPECT_CALL(resetter(), ReportStatistics(0x03u, 0x01u));
-  EXPECT_CALL(resetter(), ReportPromptResult(
-      AutomaticProfileResetter::PROMPT_NOT_TRIGGERED));
-
-  UnleashResetterAndWait();
-
-  ExpectAllMementoValuesEqualTo(kTestMementoValue);
-  EXPECT_FALSE(resetter().ShouldShowResetBanner());
-  VerifyExpectationsThenShutdownResetter();
-}
-
-TEST_F(AutomaticProfileResetterTestDryRun, AlreadyHadPrefHostedMemento) {
-  memento_in_prefs().StoreValue(kTestMementoValue);
-
-  SetTestingProgram(ConstructProgram(true, true));
-  SetTestingHashSeed(kTestHashSeed);
-
-  mock_delegate().ExpectCallsToDependenciesSetUpMethods();
-  mock_delegate().ExpectCallsToGetterMethods();
-  EXPECT_CALL(resetter(), ReportStatistics(0x03u, 0x03u));
-
-  UnleashResetterAndWait();
-
-  EXPECT_FALSE(resetter().ShouldShowResetBanner());
-  VerifyExpectationsThenShutdownResetter();
-
-  EXPECT_EQ(kTestMementoValue, memento_in_prefs().ReadValue());
-  EXPECT_EQ(std::string(), memento_in_local_state().ReadValue());
-  EXPECT_EQ(std::string(), memento_in_file().ReadValue());
-}
-
-TEST_F(AutomaticProfileResetterTestDryRun, AlreadyHadLocalStateHostedMemento) {
-  memento_in_local_state().StoreValue(kTestMementoValue);
-
-  SetTestingProgram(ConstructProgram(true, true));
-  SetTestingHashSeed(kTestHashSeed);
-
-  mock_delegate().ExpectCallsToDependenciesSetUpMethods();
-  mock_delegate().ExpectCallsToGetterMethods();
-  EXPECT_CALL(resetter(), ReportStatistics(0x03u, 0x05u));
-
-  UnleashResetterAndWait();
-
-  EXPECT_FALSE(resetter().ShouldShowResetBanner());
-  VerifyExpectationsThenShutdownResetter();
-
-  EXPECT_EQ(std::string(), memento_in_prefs().ReadValue());
-  EXPECT_EQ(kTestMementoValue, memento_in_local_state().ReadValue());
-  EXPECT_EQ(std::string(), memento_in_file().ReadValue());
-}
-
-TEST_F(AutomaticProfileResetterTestDryRun, AlreadyHadFileHostedMemento) {
-  memento_in_file().StoreValue(kTestMementoValue);
-
-  SetTestingProgram(ConstructProgram(true, true));
-  SetTestingHashSeed(kTestHashSeed);
-
-  mock_delegate().ExpectCallsToDependenciesSetUpMethods();
-  mock_delegate().ExpectCallsToGetterMethods();
-  EXPECT_CALL(resetter(), ReportStatistics(0x03u, 0x09u));
-
-  UnleashResetterAndWait();
-
-  EXPECT_FALSE(resetter().ShouldShowResetBanner());
-  VerifyExpectationsThenShutdownResetter();
-
-  EXPECT_EQ(std::string(), memento_in_prefs().ReadValue());
-  EXPECT_EQ(std::string(), memento_in_local_state().ReadValue());
-  EXPECT_EQ(kTestMementoValue, memento_in_file().ReadValue());
-}
-
-TEST_F(AutomaticProfileResetterTestDryRun, DoNothingWhenResourcesAreMissing) {
-  SetTestingProgram(std::string());
-  SetTestingHashSeed(std::string());
-
-  // No calls are expected to the delegate.
-
-  UnleashResetterAndWait();
-
-  EXPECT_FALSE(resetter().ShouldShowResetBanner());
-  VerifyExpectationsThenShutdownResetter();
-
-  ExpectAllMementoValuesEqualTo(std::string());
-}
-
-TEST_F(AutomaticProfileResetterTest, CriteriaNotSatisfied) {
-  SetTestingProgram(ConstructProgramToExerciseCriteria(false, true, true));
-  SetTestingHashSeed(kTestHashSeed);
-
-  mock_delegate().ExpectCallsToDependenciesSetUpMethods();
-  mock_delegate().ExpectCallsToGetterMethods();
-  EXPECT_CALL(resetter(), ReportStatistics(0x1fu, 0x00u));
-
-  UnleashResetterAndWait();
-
-  EXPECT_FALSE(resetter().ShouldShowResetBanner());
-  VerifyExpectationsThenShutdownResetter();
-
-  ExpectAllMementoValuesEqualTo(std::string());
-}
-
-TEST_F(AutomaticProfileResetterTest, OddCriteriaSatisfied) {
-  SetTestingProgram(ConstructProgramToExerciseCriteria(true, true, false));
-  SetTestingHashSeed(kTestHashSeed);
-
-  mock_delegate().ExpectCallsToDependenciesSetUpMethods();
-  mock_delegate().ExpectCallsToGetterMethods();
-  mock_delegate().ExpectCallToShowPrompt();
-  EXPECT_CALL(resetter(), ReportStatistics(0x15u, 0x01u));
-
-  UnleashResetterAndWait();
-
-  EXPECT_TRUE(resetter().ShouldShowResetBanner());
-  VerifyExpectationsThenShutdownResetter();
-}
-
-TEST_F(AutomaticProfileResetterTest, EvenCriteriaSatisfied) {
-  SetTestingProgram(ConstructProgramToExerciseCriteria(true, false, true));
-  SetTestingHashSeed(kTestHashSeed);
-
-  mock_delegate().ExpectCallsToDependenciesSetUpMethods();
-  mock_delegate().ExpectCallsToGetterMethods();
-  mock_delegate().ExpectCallToShowPrompt();
-  EXPECT_CALL(resetter(), ReportStatistics(0x0au, 0x01u));
-
-  UnleashResetterAndWait();
-
-  EXPECT_TRUE(resetter().ShouldShowResetBanner());
-  VerifyExpectationsThenShutdownResetter();
-}
-
-#if defined(GOOGLE_CHROME_BUILD)
-TEST_F(AutomaticProfileResetterTest, ProgramSetThroughVariationParams) {
-  SetTestingProgram(ConstructProgram(true, true));
-  SetTestingHashSeed(kTestHashSeed);
-  AllowInjectingTestDataThroughVariationParams(true);
-
-  mock_delegate().ExpectCallsToDependenciesSetUpMethods();
-  mock_delegate().ExpectCallsToGetterMethods();
-  mock_delegate().ExpectCallToShowPrompt();
-  EXPECT_CALL(resetter(), ReportStatistics(0x03u, 0x01u));
-  EXPECT_CALL(resetter(), ReportPromptResult(
-      AutomaticProfileResetter::PROMPT_SHOWN_BUBBLE));
-
-  UnleashResetterAndWait();
-  resetter().NotifyDidShowResetBubble();
-
-  ExpectAllMementoValuesEqualTo(kTestMementoValue);
-  EXPECT_TRUE(resetter().ShouldShowResetBanner());
-  VerifyExpectationsThenShutdownResetter();
-}
-#endif
-
-TEST_F(AutomaticProfileResetterTest, ConditionsSatisfiedAndInvalidMementos) {
-  memento_in_prefs().StoreValue(kTestInvalidMementoValue);
-  memento_in_local_state().StoreValue(kTestInvalidMementoValue);
-  memento_in_file().StoreValue(kTestInvalidMementoValue);
-
-  SetTestingProgram(ConstructProgram(true, true));
-  SetTestingHashSeed(kTestHashSeed);
-
-  mock_delegate().ExpectCallsToDependenciesSetUpMethods();
-  mock_delegate().ExpectCallsToGetterMethods();
-  mock_delegate().ExpectCallToShowPrompt();
-  EXPECT_CALL(resetter(), ReportStatistics(0x03u, 0x01u));
-  EXPECT_CALL(resetter(), ReportPromptResult(
-      AutomaticProfileResetter::PROMPT_SHOWN_BUBBLE));
-
-  UnleashResetterAndWait();
-  resetter().NotifyDidShowResetBubble();
-
-  ExpectAllMementoValuesEqualTo(kTestMementoValue);
-  EXPECT_TRUE(resetter().ShouldShowResetBanner());
-  VerifyExpectationsThenShutdownResetter();
-}
-
-TEST_F(AutomaticProfileResetterTest, PrefHostedMementoPreventsPrompt) {
-  memento_in_prefs().StoreValue(kTestMementoValue);
-
-  SetTestingProgram(ConstructProgram(true, true));
-  SetTestingHashSeed(kTestHashSeed);
-
-  mock_delegate().ExpectCallsToDependenciesSetUpMethods();
-  mock_delegate().ExpectCallsToGetterMethods();
-  EXPECT_CALL(resetter(), ReportStatistics(0x03u, 0x03u));
-
-  UnleashResetterAndWait();
-
-  EXPECT_TRUE(resetter().ShouldShowResetBanner());
-  VerifyExpectationsThenShutdownResetter();
-
-  EXPECT_EQ(kTestMementoValue, memento_in_prefs().ReadValue());
-  EXPECT_EQ(std::string(), memento_in_local_state().ReadValue());
-  EXPECT_EQ(std::string(), memento_in_file().ReadValue());
-}
-
-TEST_F(AutomaticProfileResetterTest, LocalStateHostedMementoPreventsPrompt) {
-  memento_in_local_state().StoreValue(kTestMementoValue);
-
-  SetTestingProgram(ConstructProgram(true, true));
-  SetTestingHashSeed(kTestHashSeed);
-
-  mock_delegate().ExpectCallsToDependenciesSetUpMethods();
-  mock_delegate().ExpectCallsToGetterMethods();
-  EXPECT_CALL(resetter(), ReportStatistics(0x03u, 0x05u));
-
-  UnleashResetterAndWait();
-
-  EXPECT_TRUE(resetter().ShouldShowResetBanner());
-  VerifyExpectationsThenShutdownResetter();
-
-  EXPECT_EQ(std::string(), memento_in_prefs().ReadValue());
-  EXPECT_EQ(kTestMementoValue, memento_in_local_state().ReadValue());
-  EXPECT_EQ(std::string(), memento_in_file().ReadValue());
-}
-
-TEST_F(AutomaticProfileResetterTest, FileHostedMementoPreventsPrompt) {
-  memento_in_file().StoreValue(kTestMementoValue);
-
-  SetTestingProgram(ConstructProgram(true, true));
-  SetTestingHashSeed(kTestHashSeed);
-
-  mock_delegate().ExpectCallsToDependenciesSetUpMethods();
-  mock_delegate().ExpectCallsToGetterMethods();
-  EXPECT_CALL(resetter(), ReportStatistics(0x03u, 0x09u));
-
-  UnleashResetterAndWait();
-
-  EXPECT_TRUE(resetter().ShouldShowResetBanner());
-  VerifyExpectationsThenShutdownResetter();
-
-  EXPECT_EQ(std::string(), memento_in_prefs().ReadValue());
-  EXPECT_EQ(std::string(), memento_in_local_state().ReadValue());
-  EXPECT_EQ(kTestMementoValue, memento_in_file().ReadValue());
-}
-
-TEST_F(AutomaticProfileResetterTest, DoNothingWhenResourcesAreMissing) {
-  SetTestingProgram(std::string());
-  SetTestingHashSeed(std::string());
-
-  // No calls are expected to the delegate.
-
-  UnleashResetterAndWait();
-
-  EXPECT_FALSE(resetter().ShouldShowResetBanner());
-  VerifyExpectationsThenShutdownResetter();
-
-  ExpectAllMementoValuesEqualTo(std::string());
-}
-
-TEST_F(AutomaticProfileResetterTest, PromptSuppressed) {
-  OrchestrateThroughEvaluationFlow();
-
-  VerifyExpectationsThenShutdownResetter();
-
-  ExpectAllMementoValuesEqualTo(std::string());
-}
-
-TEST_F(AutomaticProfileResetterTest, PromptNotSupported) {
-  SetTestingProgram(ConstructProgram(true, true));
-  SetTestingHashSeed(kTestHashSeed);
-
-  mock_delegate().ExpectCallsToDependenciesSetUpMethods();
-  mock_delegate().ExpectCallsToGetterMethods();
-  EXPECT_CALL(mock_delegate(), TriggerPrompt())
-      .WillOnce(testing::Return(false));
-  EXPECT_CALL(resetter(), ReportStatistics(0x03u, 0x01u));
-  EXPECT_CALL(resetter(), ReportPromptResult(
-      AutomaticProfileResetter::PROMPT_NOT_TRIGGERED));
-
-  UnleashResetterAndWait();
-
-  ExpectAllMementoValuesEqualTo(kTestMementoValue);
-  EXPECT_TRUE(resetter().ShouldShowResetBanner());
-  VerifyExpectationsThenShutdownResetter();
-}
-
-TEST_F(AutomaticProfileResetterTest, PromptIgnored) {
-  OrchestrateThroughEvaluationFlow();
-
-  EXPECT_CALL(resetter(), ReportPromptResult(
-      AutomaticProfileResetter::PROMPT_SHOWN_BUBBLE));
-  resetter().NotifyDidShowResetBubble();
-  ExpectAllMementoValuesEqualTo(kTestMementoValue);
-  VerifyExpectationsThenShutdownResetter();
-}
-
-TEST_F(AutomaticProfileResetterTest, PromptActionReset) {
-  OrchestrateThroughEvaluationFlow();
-
-  EXPECT_CALL(resetter(), ReportPromptResult(
-      AutomaticProfileResetter::PROMPT_SHOWN_BUBBLE));
-  resetter().NotifyDidShowResetBubble();
-  ExpectAllMementoValuesEqualTo(kTestMementoValue);
-  testing::Mock::VerifyAndClearExpectations(&resetter());
-
-  mock_delegate().ExpectCallToTriggerReset(false);
-  EXPECT_CALL(resetter(), ReportPromptResult(
-      AutomaticProfileResetter::PROMPT_ACTION_RESET));
-  resetter().TriggerProfileReset(false /*send_feedback*/);
-  testing::Mock::VerifyAndClearExpectations(&resetter());
-  testing::Mock::VerifyAndClearExpectations(&mock_delegate());
-
-  EXPECT_CALL(mock_delegate(), DismissPrompt());
-  mock_delegate().EmulateProfileResetCompleted();
-  EXPECT_FALSE(resetter().ShouldShowResetBanner());
-  VerifyExpectationsThenShutdownResetter();
-}
-
-TEST_F(AutomaticProfileResetterTest, PromptActionResetWithFeedback) {
-  OrchestrateThroughEvaluationFlow();
-
-  EXPECT_CALL(resetter(), ReportPromptResult(
-      AutomaticProfileResetter::PROMPT_SHOWN_BUBBLE));
-  resetter().NotifyDidShowResetBubble();
-  ExpectAllMementoValuesEqualTo(kTestMementoValue);
-  testing::Mock::VerifyAndClearExpectations(&resetter());
-
-  mock_delegate().ExpectCallToTriggerReset(true);
-  EXPECT_CALL(resetter(), ReportPromptResult(
-      AutomaticProfileResetter::PROMPT_ACTION_RESET));
-  resetter().TriggerProfileReset(true /*send_feedback*/);
-  testing::Mock::VerifyAndClearExpectations(&resetter());
-  testing::Mock::VerifyAndClearExpectations(&mock_delegate());
-
-  EXPECT_CALL(mock_delegate(), DismissPrompt());
-  mock_delegate().EmulateProfileResetCompleted();
-  EXPECT_FALSE(resetter().ShouldShowResetBanner());
-  VerifyExpectationsThenShutdownResetter();
-}
-
-TEST_F(AutomaticProfileResetterTest, PromptActionNoReset) {
-  OrchestrateThroughEvaluationFlow();
-
-  EXPECT_CALL(resetter(), ReportPromptResult(
-      AutomaticProfileResetter::PROMPT_SHOWN_BUBBLE));
-  resetter().NotifyDidShowResetBubble();
-  ExpectAllMementoValuesEqualTo(kTestMementoValue);
-  testing::Mock::VerifyAndClearExpectations(&resetter());
-
-  EXPECT_CALL(mock_delegate(), DismissPrompt());
-  EXPECT_CALL(resetter(), ReportPromptResult(
-      AutomaticProfileResetter::PROMPT_ACTION_NO_RESET));
-  resetter().SkipProfileReset();
-  EXPECT_FALSE(resetter().ShouldShowResetBanner());
-  VerifyExpectationsThenShutdownResetter();
-}
-
-TEST_F(AutomaticProfileResetterTest, PromptFollowedByWebUIReset) {
-  OrchestrateThroughEvaluationFlow();
-
-  EXPECT_CALL(resetter(), ReportPromptResult(
-      AutomaticProfileResetter::PROMPT_SHOWN_BUBBLE));
-  resetter().NotifyDidShowResetBubble();
-  ExpectAllMementoValuesEqualTo(kTestMementoValue);
-  testing::Mock::VerifyAndClearExpectations(&resetter());
-
-  EXPECT_CALL(mock_delegate(), DismissPrompt());
-  resetter().NotifyDidOpenWebUIResetDialog();
-  testing::Mock::VerifyAndClearExpectations(&mock_delegate());
-
-  EXPECT_CALL(resetter(), ReportPromptResult(
-      AutomaticProfileResetter::PROMPT_FOLLOWED_BY_WEBUI_RESET));
-  resetter().NotifyDidCloseWebUIResetDialog(true);
-  EXPECT_TRUE(resetter().ShouldShowResetBanner());
-  VerifyExpectationsThenShutdownResetter();
-}
-
-TEST_F(AutomaticProfileResetterTest, PromptFollowedByWebUINoReset) {
-  OrchestrateThroughEvaluationFlow();
-
-  EXPECT_CALL(resetter(), ReportPromptResult(
-      AutomaticProfileResetter::PROMPT_SHOWN_BUBBLE));
-  resetter().NotifyDidShowResetBubble();
-  ExpectAllMementoValuesEqualTo(kTestMementoValue);
-  testing::Mock::VerifyAndClearExpectations(&resetter());
-
-  EXPECT_CALL(mock_delegate(), DismissPrompt());
-  resetter().NotifyDidOpenWebUIResetDialog();
-  testing::Mock::VerifyAndClearExpectations(&mock_delegate());
-
-  EXPECT_CALL(resetter(), ReportPromptResult(
-      AutomaticProfileResetter::PROMPT_FOLLOWED_BY_WEBUI_NO_RESET));
-  resetter().NotifyDidCloseWebUIResetDialog(false);
-  EXPECT_TRUE(resetter().ShouldShowResetBanner());
-  VerifyExpectationsThenShutdownResetter();
-}
-
-TEST_F(AutomaticProfileResetterTest, PromptFollowedByIncidentalWebUIReset) {
-  OrchestrateThroughEvaluationFlow();
-
-  EXPECT_CALL(resetter(), ReportPromptResult(
-      AutomaticProfileResetter::PROMPT_SHOWN_BUBBLE));
-  resetter().NotifyDidShowResetBubble();
-  ExpectAllMementoValuesEqualTo(kTestMementoValue);
-  testing::Mock::VerifyAndClearExpectations(&resetter());
-
-  // Missing NotifyDidOpenWebUIResetDialog().
-  // This can arise if a settings page was already opened at the time the prompt
-  // was triggered, and this already opened dialog was used to initiate a reset
-  // after having dismissed the prompt.
-
-  EXPECT_CALL(mock_delegate(), DismissPrompt());
-  EXPECT_CALL(resetter(), ReportPromptResult(
-      AutomaticProfileResetter::PROMPT_FOLLOWED_BY_WEBUI_RESET));
-  resetter().NotifyDidCloseWebUIResetDialog(true);
-  EXPECT_TRUE(resetter().ShouldShowResetBanner());
-  VerifyExpectationsThenShutdownResetter();
-}
-
-TEST_F(AutomaticProfileResetterTest, PromptSuppressedButHadWebUIReset) {
-  OrchestrateThroughEvaluationFlow();
-
-  EXPECT_CALL(mock_delegate(), DismissPrompt());
-  resetter().NotifyDidOpenWebUIResetDialog();
-  testing::Mock::VerifyAndClearExpectations(&mock_delegate());
-
-  EXPECT_CALL(resetter(), ReportPromptResult(
-      AutomaticProfileResetter::PROMPT_NOT_SHOWN_BUBBLE_BUT_HAD_WEBUI_RESET));
-  resetter().NotifyDidCloseWebUIResetDialog(true);
-  ExpectAllMementoValuesEqualTo(kTestMementoValue);
-  EXPECT_TRUE(resetter().ShouldShowResetBanner());
-  VerifyExpectationsThenShutdownResetter();
-}
-
-TEST_F(AutomaticProfileResetterTest, PromptSuppressedButHadWebUINoReset) {
-  OrchestrateThroughEvaluationFlow();
-
-  EXPECT_CALL(mock_delegate(), DismissPrompt());
-  resetter().NotifyDidOpenWebUIResetDialog();
-  testing::Mock::VerifyAndClearExpectations(&mock_delegate());
-
-  EXPECT_CALL(resetter(), ReportPromptResult(AutomaticProfileResetter::
-      PROMPT_NOT_SHOWN_BUBBLE_BUT_HAD_WEBUI_NO_RESET));
-  resetter().NotifyDidCloseWebUIResetDialog(false);
-  ExpectAllMementoValuesEqualTo(kTestMementoValue);
-  EXPECT_TRUE(resetter().ShouldShowResetBanner());
-  VerifyExpectationsThenShutdownResetter();
-}
-
-TEST_F(AutomaticProfileResetterTest, BannerDismissed) {
-  OrchestrateThroughEvaluationFlow();
-
-  EXPECT_CALL(resetter(), ReportPromptResult(
-      AutomaticProfileResetter::PROMPT_SHOWN_BUBBLE));
-  resetter().NotifyDidShowResetBubble();
-  ExpectAllMementoValuesEqualTo(kTestMementoValue);
-  testing::Mock::VerifyAndClearExpectations(&resetter());
-
-  resetter().NotifyDidCloseWebUIResetBanner();
-
-  EXPECT_TRUE(resetter().IsResetPromptFlowActive());
-  EXPECT_FALSE(resetter().ShouldShowResetBanner());
-
-  // Note: we use strict mocks, so this also checks the bubble is not closed.
-  VerifyExpectationsThenShutdownResetter();
-}
-
-TEST_F(AutomaticProfileResetterTest, BannerDismissedWhilePromptSuppressed) {
-  OrchestrateThroughEvaluationFlow();
-
-  resetter().NotifyDidCloseWebUIResetBanner();
-
-  EXPECT_TRUE(resetter().IsResetPromptFlowActive());
-  EXPECT_FALSE(resetter().ShouldShowResetBanner());
-  VerifyExpectationsThenShutdownResetter();
-
-  ExpectAllMementoValuesEqualTo(std::string());
-}
-
-// Please see comments above ConstructProgramToCheckPreferences() to understand
-// how the following tests work.
-
-TEST_F(AutomaticProfileResetterTest, InputUserPreferencesCorrect) {
-  SetTestingProgram(ConstructProgramToCheckPreferences());
-  SetTestingHashSeed(kTestHashSeed);
-
-  PrefService* prefs = profile()->GetPrefs();
-  prefs->SetString(kTestPreferencePath, kTestPreferenceValue);
-
-  mock_delegate().ExpectCallsToDependenciesSetUpMethods();
-  mock_delegate().ExpectCallsToGetterMethods();
-  uint32 expected_mask = HAS_EXPECTED_USER_PREFERENCE |
-                         USER_PREFERENCE_IS_USER_CONTROLLED;
-  EXPECT_CALL(resetter(), ReportStatistics(0x00u, expected_mask));
-
-  UnleashResetterAndWait();
-}
-
-TEST_F(AutomaticProfileResetterTest, InputLocalStateCorrect) {
-  SetTestingProgram(ConstructProgramToCheckPreferences());
-  SetTestingHashSeed(kTestHashSeed);
-
-  PrefService* prefs = local_state();
-  prefs->SetString(kTestPreferencePath, kTestPreferenceValue);
-
-  mock_delegate().ExpectCallsToDependenciesSetUpMethods();
-  mock_delegate().ExpectCallsToGetterMethods();
-  uint32 expected_mask = HAS_EXPECTED_LOCAL_STATE_PREFERENCE |
-                         LOCAL_STATE_IS_USER_CONTROLLED;
-  EXPECT_CALL(resetter(), ReportStatistics(0x00u, expected_mask));
-
-  UnleashResetterAndWait();
-}
-
-TEST_F(AutomaticProfileResetterTest, InputManagedUserPreferencesCorrect) {
-  SetTestingProgram(ConstructProgramToCheckPreferences());
-  SetTestingHashSeed(kTestHashSeed);
-
-  syncable_prefs::TestingPrefServiceSyncable* prefs =
-      profile()->GetTestingPrefService();
-  prefs->SetManagedPref(kTestPreferencePath,
-                        new base::StringValue(kTestPreferenceValue));
-
-  mock_delegate().ExpectCallsToDependenciesSetUpMethods();
-  mock_delegate().ExpectCallsToGetterMethods();
-  uint32 expected_mask = HAS_EXPECTED_USER_PREFERENCE;
-  EXPECT_CALL(resetter(), ReportStatistics(0x00u, expected_mask));
-
-  UnleashResetterAndWait();
-}
-
-TEST_F(AutomaticProfileResetterTest, InputManagedLocalStateCorrect) {
-  SetTestingProgram(ConstructProgramToCheckPreferences());
-  SetTestingHashSeed(kTestHashSeed);
-
-  TestingPrefServiceSimple* prefs = local_state();
-  prefs->SetManagedPref(kTestPreferencePath,
-                        new base::StringValue(kTestPreferenceValue));
-
-  mock_delegate().ExpectCallsToDependenciesSetUpMethods();
-  mock_delegate().ExpectCallsToGetterMethods();
-  uint32 expected_mask = HAS_EXPECTED_LOCAL_STATE_PREFERENCE;
-  EXPECT_CALL(resetter(), ReportStatistics(0x00u, expected_mask));
-
-  UnleashResetterAndWait();
-}
-
-// Please see comments above ConstructProgramToCheckSearchEngines() to
-// understand how the following tests work.
-
-TEST_F(AutomaticProfileResetterTest, InputDefaultSearchProviderCorrect) {
-  SetTestingProgram(ConstructProgramToCheckSearchEngines());
-  SetTestingHashSeed(kTestHashSeed);
-
-  mock_delegate().emulated_default_search_provider_details().SetString(
-      kSearchURLAttributeKey, kTestSearchURL);
-
-  mock_delegate().ExpectCallsToDependenciesSetUpMethods();
-  mock_delegate().ExpectCallsToGetterMethods();
-  uint32 expected_mask = HAS_EXPECTED_DEFAULT_SEARCH_PROVIDER |
-                         DEFAULT_SEARCH_PROVIDER_IS_USER_CONTROLLED;
-  EXPECT_CALL(resetter(), ReportStatistics(0x00u, expected_mask));
-
-  UnleashResetterAndWait();
-}
-
-TEST_F(AutomaticProfileResetterTest, InputSearchProviderManagedCorrect) {
-  SetTestingProgram(ConstructProgramToCheckSearchEngines());
-  SetTestingHashSeed(kTestHashSeed);
-
-  mock_delegate().emulated_default_search_provider_details().SetString(
-      kSearchURLAttributeKey, kTestSearchURL);
-  mock_delegate().set_emulated_is_default_search_provider_managed(true);
-
-  mock_delegate().ExpectCallsToDependenciesSetUpMethods();
-  mock_delegate().ExpectCallsToGetterMethods();
-  uint32 expected_mask = HAS_EXPECTED_DEFAULT_SEARCH_PROVIDER;
-  EXPECT_CALL(resetter(), ReportStatistics(0x00u, expected_mask));
-
-  UnleashResetterAndWait();
-}
-
-TEST_F(AutomaticProfileResetterTest, InputSearchProvidersCorrect) {
-  SetTestingProgram(ConstructProgramToCheckSearchEngines());
-  SetTestingHashSeed(kTestHashSeed);
-
-  base::DictionaryValue* search_provider_1 = new base::DictionaryValue;
-  base::DictionaryValue* search_provider_2 = new base::DictionaryValue;
-  search_provider_1->SetString(kSearchURLAttributeKey, kTestSearchURL);
-  search_provider_2->SetString(kSearchURLAttributeKey, kTestSearchURL2);
-  mock_delegate().emulated_search_providers_details().Append(search_provider_1);
-  mock_delegate().emulated_search_providers_details().Append(search_provider_2);
-
-  mock_delegate().ExpectCallsToDependenciesSetUpMethods();
-  mock_delegate().ExpectCallsToGetterMethods();
-  uint32 expected_mask = DEFAULT_SEARCH_PROVIDER_IS_USER_CONTROLLED |
-                         HAS_EXPECTED_PREPOPULATED_SEARCH_PROVIDER_1 |
-                         HAS_EXPECTED_PREPOPULATED_SEARCH_PROVIDER_2;
-  EXPECT_CALL(resetter(), ReportStatistics(0x00u, expected_mask));
-
-  UnleashResetterAndWait();
-}
-
-// Please see comments above ConstructProgramToCheckLoadedModuleDigests() to
-// understand how the following tests work.
-
-TEST_F(AutomaticProfileResetterTest, InputModuleDigestsCorrect) {
-  SetTestingProgram(ConstructProgramToCheckLoadedModuleDigests());
-  SetTestingHashSeed(kTestHashSeed);
-
-  mock_delegate().emulated_loaded_module_digests().AppendString(
-      kTestModuleDigest);
-  mock_delegate().emulated_loaded_module_digests().AppendString(
-      kTestModuleDigest2);
-
-  mock_delegate().ExpectCallsToDependenciesSetUpMethods();
-  mock_delegate().ExpectCallsToGetterMethods();
-  uint32 expected_mask =
-      HAS_EXPECTED_MODULE_DIGEST_1 | HAS_EXPECTED_MODULE_DIGEST_2;
-  EXPECT_CALL(resetter(), ReportStatistics(0x00u, expected_mask));
-
-  UnleashResetterAndWait();
-}
-
-}  // namespace
diff --git a/chrome/browser/profile_resetter/jtl_foundation.cc b/chrome/browser/profile_resetter/jtl_foundation.cc
deleted file mode 100644
index a2a2007..0000000
--- a/chrome/browser/profile_resetter/jtl_foundation.cc
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/profile_resetter/jtl_foundation.h"
-
-#include "base/logging.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_util.h"
-
-namespace jtl_foundation {
-
-Hasher::Hasher(const std::string& seed) : hmac_(crypto::HMAC::SHA256) {
-  if (!hmac_.Init(seed))
-    NOTREACHED();
-}
-
-Hasher::~Hasher() {}
-
-std::string Hasher::GetHash(const std::string& input) const {
-  if (cached_hashes_.find(input) == cached_hashes_.end()) {
-    // Calculate value.
-    unsigned char digest[kHashSizeInBytes];
-    if (!hmac_.Sign(input, digest, arraysize(digest))) {
-      NOTREACHED();
-      return std::string();
-    }
-    // Instead of using the full SHA256, we only use the hex encoding of the
-    // first 16 bytes.
-    cached_hashes_[input] = base::HexEncode(digest, kHashSizeInBytes / 2);
-    DCHECK_EQ(kHashSizeInBytes, cached_hashes_[input].size());
-  }
-  return cached_hashes_[input];
-}
-
-// static
-bool Hasher::IsHash(const std::string& maybe_hash) {
-  if (maybe_hash.size() != kHashSizeInBytes)
-    return false;
-  for (std::string::const_iterator it = maybe_hash.begin();
-       it != maybe_hash.end(); ++it) {
-    if (!base::IsHexDigit(*it))
-      return false;
-  }
-  return true;
-}
-
-}  // namespace jtl_foundation
diff --git a/chrome/browser/profile_resetter/jtl_foundation.h b/chrome/browser/profile_resetter/jtl_foundation.h
deleted file mode 100644
index cc4a5f4..0000000
--- a/chrome/browser/profile_resetter/jtl_foundation.h
+++ /dev/null
@@ -1,193 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_PROFILE_RESETTER_JTL_FOUNDATION_H_
-#define CHROME_BROWSER_PROFILE_RESETTER_JTL_FOUNDATION_H_
-
-#include <map>
-#include <string>
-
-#include "base/basictypes.h"
-#include "crypto/hmac.h"
-
-namespace jtl_foundation {
-
-// A JTL (JSON Traversal Language) program is composed of one or more
-// sentences. Each sentence consists of a sequence of operations. The input of
-// the program is a hierarchical JSON data structure.
-//
-// The execution of each sentence starts at the root of an input dictionary. The
-// operations include navigation in the JSON data structure, as well as
-// comparing the current (leaf) node to fixed values. The program also has a
-// separate dictionary as working memory, into which it can memorize data, then
-// later recall it for comparisons.
-//
-// Example program:
-// NAVIGATE_ANY
-// NAVIGATE(hash("bar"))
-// COMPARE_NODE_BOOL(1)
-// STORE_BOOL(hash("found_foo"), 1)
-// STOP_EXECUTING_SENTENCE
-//
-// Example input:
-// {
-//   'key1': 1,
-//   'key2': {'foo': 0, 'bar': false, 'baz': 2}
-//   'key3': {'foo': 0, 'bar': true, 'baz': 2}
-//   'key4': {'foo': 0, 'bar': true, 'baz': 2}
-// }
-//
-// This program navigates from the root of the dictionary to all children
-// ("key1", "key2", "key3", "key4") and executes the remaining program on each
-// of the children. The navigation happens in depth-first pre-order. On each of
-// the children it tries to navigate into the child "bar", which fails for
-// "key1", so execution stops for this sub-branch. On key2 the program navigates
-// to "bar" and moves the execution context to this node which has the value
-// "false". Therefore, the following COMPARE_NODE_BOOL is not fulfilled and the
-// execution does not continue on this branch, so we back track and proceed with
-// "key3" and its "bar" child. For this node, COMPARE_NODE_BOOL is fulfilled and
-// the execution continues to store "found_foo = true" into the working memory
-// of the interpreter. Next the interpreter executes STOP_EXECUTING_SENTENCE
-// which prevents the traversal from descending into the "key4" branch from the
-// NAVIGATE_ANY operation and can therefore speedup the processing.
-//
-// All node names, and node values of type string, integer and double are hashed
-// before being compared to hash values listed in |program|.
-
-// JTL byte code consists of uint8 opcodes followed by parameters. Parameters
-// are either boolean (uint8 with value \x00 or \x01), uint32 (in little-endian
-// notation), or hash string of 32 bytes.
-// The following opcodes are defined:
-enum OpCodes {
-  // Continues execution with the next operation on the element of a
-  // dictionary that matches the passed key parameter. If no such element
-  // exists, the command execution returns from the current instruction.
-  // Parameters:
-  // - a 32 byte hash of the target dictionary key.
-  NAVIGATE = 0x00,
-  // Continues execution with the next operation on each element of a
-  // dictionary or list. If no such element exists or the current element is
-  // neither a dictionary or list, the command execution returns from the
-  // current instruction.
-  NAVIGATE_ANY = 0x01,
-  // Continues execution with the next operation on the parent node of the
-  // current node. If the current node is the root of the input dictionary, the
-  // program execution fails with a runtime error.
-  NAVIGATE_BACK = 0x02,
-  // Stores a boolean value in the working memory.
-  // Parameters:
-  // - a 32 byte hash of the parameter name,
-  // - the value to store (\x00 or \x01)
-  STORE_BOOL = 0x10,
-  // Checks whether a boolean stored in working memory matches the expected
-  // value and continues execution with the next operation in case of a match.
-  // Parameters:
-  // - a 32 byte hash of the parameter name,
-  // - the expected value (\x00 or \x01),
-  // - the default value in case the working memory contains no corresponding
-  //   entry (\x00 or\x01).
-  COMPARE_STORED_BOOL = 0x11,
-  // Same as STORE_BOOL but takes a hash instead of a boolean value as
-  // parameter.
-  STORE_HASH = 0x12,
-  // Same as COMPARE_STORED_BOOL but takes a hash instead of two boolean values
-  // as parameters.
-  COMPARE_STORED_HASH = 0x13,
-  // Stores the current node into the working memory. If the current node is not
-  // a boolean value, the program execution returns from the current
-  // instruction.
-  // Parameters:
-  // - a 32 byte hash of the parameter name.
-  STORE_NODE_BOOL = 0x14,
-  // Stores the hashed value of the current node into the working memory. If
-  // the current node is not a string, integer or double, the program execution
-  // returns from the current instruction.
-  // Parameters:
-  // - a 32 byte hash of the parameter name.
-  STORE_NODE_HASH = 0x15,
-  // Parses the value of the current node as a URL, extracts the subcomponent of
-  // the domain name that is immediately below the registrar-controlled portion,
-  // and stores the hash of this subcomponent into working memory. In case the
-  // domain name ends in a suffix not on the Public Suffix List (i.e. is neither
-  // an ICANN, nor a private domain suffix), the last subcomponent is assumed to
-  // be the registry, and the second-to-last subcomponent is extracted.
-  // If the current node is not a string that represents a URL, or if this URL
-  // does not have a domain component as described above, the program execution
-  // returns from the current instruction.
-  // For example, "foo.com", "www.foo.co.uk", "foo.appspot.com", and "foo.bar"
-  // will all yield (the hash of) "foo" as a result.
-  // See the unit test for more details.
-  // Parameters:
-  // - a 32 byte hash of the parameter name.
-  STORE_NODE_REGISTERABLE_DOMAIN_HASH = 0x16,
-  // Compares the current node against a boolean value and continues execution
-  // with the next operation in case of a match. If the current node does not
-  // match or is not a boolean value, the program execution returns from the
-  // current instruction.
-  // Parameters:
-  // - a boolean value (\x00 or \x01).
-  COMPARE_NODE_BOOL = 0x20,
-  // Compares the hashed value of the current node against the given hash, and
-  // continues execution with the next operation in case of a match. If the
-  // current node is not a string, integer or double, or if it is either, but
-  // its hash does not match, the program execution returns from the current
-  // instruction.
-  // Parameters:
-  // - a 32 byte hash of the expected value.
-  COMPARE_NODE_HASH = 0x21,
-  // The negation of the above.
-  COMPARE_NODE_HASH_NOT = 0x22,
-  // Compares the current node against a boolean value stored in working memory,
-  // and continues with the next operation in case of a match. If the current
-  // node is not a boolean value, the working memory contains no corresponding
-  // boolean value, or if they do not match, the program execution returns from
-  // the current instruction.
-  // Parameters:
-  // - a 32 byte hash of the parameter name.
-  COMPARE_NODE_TO_STORED_BOOL = 0x23,
-  // Compares the hashed value of the current node against a hash value stored
-  // in working memory, and continues with the next operation in case of a
-  // match. If the current node is not a string, integer or double, or if the
-  // working memory contains no corresponding hash string, or if the hashes do
-  // not match, the program execution returns from the current instruction.
-  // Parameters:
-  // - a 32 byte hash of the parameter name.
-  COMPARE_NODE_TO_STORED_HASH = 0x24,
-  // Checks whether the current node is a string value that contains the given
-  // pattern as a substring, and continues execution with the next operation in
-  // case it does. If the current node is not a string, or if does not match the
-  // pattern, the program execution returns from the current instruction.
-  // Parameters:
-  // - a 32 byte hash of the pattern,
-  // - a 4 byte unsigned integer: the length (>0) of the pattern in bytes,
-  // - a 4 byte unsigned integer: the sum of all bytes in the pattern, serving
-  //   as a heuristic to reduce the number of actual SHA-256 calculations.
-  COMPARE_NODE_SUBSTRING = 0x25,
-  // Stop execution in this specific sentence.
-  STOP_EXECUTING_SENTENCE = 0x30,
-  // Separator between sentences, starts a new sentence.
-  END_OF_SENTENCE = 0x31
-};
-
-const size_t kHashSizeInBytes = 32u;
-
-// A class that provides SHA256 hash values for strings using a fixed hash seed.
-class Hasher {
- public:
-  explicit Hasher(const std::string& seed);
-  ~Hasher();
-
-  std::string GetHash(const std::string& input) const;
-
-  static bool IsHash(const std::string& maybe_hash);
-
- private:
-  crypto::HMAC hmac_;
-  mutable std::map<std::string, std::string> cached_hashes_;
-  DISALLOW_COPY_AND_ASSIGN(Hasher);
-};
-
-}  // namespace jtl_foundation
-
-#endif  // CHROME_BROWSER_PROFILE_RESETTER_JTL_FOUNDATION_H_
diff --git a/chrome/browser/profile_resetter/jtl_instructions.h b/chrome/browser/profile_resetter/jtl_instructions.h
deleted file mode 100644
index 76b57a67..0000000
--- a/chrome/browser/profile_resetter/jtl_instructions.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_PROFILE_RESETTER_JTL_INSTRUCTIONS_H_
-#define CHROME_BROWSER_PROFILE_RESETTER_JTL_INSTRUCTIONS_H_
-
-#include <string>
-
-// These are instructions to generate binary code for JTL programs.
-
-#define VALUE_FALSE std::string(1, '\x00')
-#define VALUE_TRUE std::string(1, '\x01')
-
-#define OP_NAVIGATE(key) std::string(1, '\x00') + key
-#define OP_NAVIGATE_ANY std::string(1, '\x01')
-#define OP_NAVIGATE_BACK std::string(1, '\x02')
-#define OP_STORE_BOOL(name, value) std::string(1, '\x10') + name + value
-#define OP_COMPARE_STORED_BOOL(name, value, default_value) \
-    std::string(1, '\x11') + name + value + default_value
-#define OP_STORE_HASH(name, value) std::string(1, '\x12') + name + value
-#define OP_COMPARE_STORED_HASH(name, value, default_value) \
-    std::string(1, '\x13') + name + value + default_value
-#define OP_STORE_NODE_BOOL(name) std::string(1, '\x14') + name
-#define OP_STORE_NODE_HASH(name) std::string(1, '\x15') + name
-#define OP_STORE_NODE_REGISTERABLE_DOMAIN_HASH(name) \
-    std::string(1, '\x16') + name
-#define OP_COMPARE_NODE_BOOL(value) std::string(1, '\x20') + value
-#define OP_COMPARE_NODE_HASH(value) std::string(1, '\x21') + value
-#define OP_COMPARE_NODE_HASH_NOT(value) std::string(1, '\x22') + value
-#define OP_COMPARE_NODE_TO_STORED_BOOL(name) std::string(1, '\x23') + name
-#define OP_COMPARE_NODE_TO_STORED_HASH(name) std::string(1, '\x24') + name
-#define OP_COMPARE_NODE_SUBSTRING(pattern, pattern_length, pattern_sum) \
-    std::string(1, '\x25') + pattern + pattern_length + pattern_sum
-#define OP_STOP_EXECUTING_SENTENCE std::string(1, '\x30')
-#define OP_END_OF_SENTENCE std::string(1, '\x31')
-
-#endif  // CHROME_BROWSER_PROFILE_RESETTER_JTL_INSTRUCTIONS_H_
diff --git a/chrome/browser/profile_resetter/jtl_interpreter.cc b/chrome/browser/profile_resetter/jtl_interpreter.cc
deleted file mode 100644
index be0b368c..0000000
--- a/chrome/browser/profile_resetter/jtl_interpreter.cc
+++ /dev/null
@@ -1,746 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/profile_resetter/jtl_interpreter.h"
-
-#include <numeric>
-
-#include "base/memory/scoped_vector.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_util.h"
-#include "chrome/browser/profile_resetter/jtl_foundation.h"
-#include "crypto/hmac.h"
-#include "crypto/sha2.h"
-#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
-#include "url/gurl.h"
-
-namespace {
-
-class ExecutionContext;
-
-// An operation in an interpreted program.
-class Operation {
- public:
-  virtual ~Operation() {}
-  // Executes the operation on the specified context and instructs the context
-  // to continue execution with the next instruction if appropriate.
-  // Returns true if we should continue with any potential backtracking that
-  // needs to be done.
-  virtual bool Execute(ExecutionContext* context) = 0;
-};
-
-// An execution context of operations.
-class ExecutionContext {
- public:
-  // |input| is the root of a dictionary that stores the information the
-  // sentence is evaluated on.
-  ExecutionContext(const jtl_foundation::Hasher* hasher,
-                   const std::vector<Operation*>& sentence,
-                   const base::DictionaryValue* input,
-                   base::DictionaryValue* working_memory)
-      : hasher_(hasher),
-        sentence_(sentence),
-        next_instruction_index_(0u),
-        working_memory_(working_memory),
-        error_(false) {
-    stack_.push_back(input);
-  }
-  ~ExecutionContext() {}
-
-  // Returns true in case of success.
-  bool ContinueExecution() {
-    if (error_ || stack_.empty()) {
-      error_ = true;
-      return false;
-    }
-    if (next_instruction_index_ >= sentence_.size())
-      return true;
-
-    Operation* op = sentence_[next_instruction_index_];
-    next_instruction_index_++;
-    bool continue_traversal = op->Execute(this);
-    next_instruction_index_--;
-    return continue_traversal;
-  }
-
-  std::string GetHash(const std::string& input) {
-    return hasher_->GetHash(input);
-  }
-
-  // Calculates the |hash| of a string, integer or double |value|, and returns
-  // true. Returns false otherwise.
-  bool GetValueHash(const base::Value& value, std::string* hash) {
-    DCHECK(hash);
-    std::string value_as_string;
-    int tmp_int = 0;
-    double tmp_double = 0.0;
-    if (value.GetAsInteger(&tmp_int))
-      value_as_string = base::IntToString(tmp_int);
-    else if (value.GetAsDouble(&tmp_double))
-      value_as_string = base::DoubleToString(tmp_double);
-    else if (!value.GetAsString(&value_as_string))
-      return false;
-    *hash = GetHash(value_as_string);
-    return true;
-  }
-
-  const base::Value* current_node() const { return stack_.back(); }
-  std::vector<const base::Value*>* stack() { return &stack_; }
-  base::DictionaryValue* working_memory() { return working_memory_; }
-  bool error() const { return error_; }
-
- private:
-  // A hasher used to hash node names in a dictionary.
-  const jtl_foundation::Hasher* hasher_;
-  // The sentence to be executed.
-  const std::vector<Operation*> sentence_;
-  // Position in |sentence_|.
-  size_t next_instruction_index_;
-  // A stack of Values, indicating a navigation path from the root node of
-  // |input| (see constructor) to the current node on which the
-  // sentence_[next_instruction_index_] is evaluated.
-  std::vector<const base::Value*> stack_;
-  // Memory into which values can be stored by the program.
-  base::DictionaryValue* working_memory_;
-  // Whether a runtime error occurred.
-  bool error_;
-  DISALLOW_COPY_AND_ASSIGN(ExecutionContext);
-};
-
-class NavigateOperation : public Operation {
- public:
-  explicit NavigateOperation(const std::string& hashed_key)
-      : hashed_key_(hashed_key) {}
-  ~NavigateOperation() override {}
-  bool Execute(ExecutionContext* context) override {
-    const base::DictionaryValue* dict = NULL;
-    if (!context->current_node()->GetAsDictionary(&dict)) {
-      // Just ignore this node gracefully as this navigation is a dead end.
-      // If this NavigateOperation occurred after a NavigateAny operation, those
-      // may still be fulfillable, so we allow continuing the execution of the
-      // sentence on other nodes.
-      return true;
-    }
-    for (base::DictionaryValue::Iterator i(*dict); !i.IsAtEnd(); i.Advance()) {
-      if (context->GetHash(i.key()) != hashed_key_)
-        continue;
-      context->stack()->push_back(&i.value());
-      bool continue_traversal = context->ContinueExecution();
-      context->stack()->pop_back();
-      if (!continue_traversal)
-        return false;
-    }
-    return true;
-  }
-
- private:
-  std::string hashed_key_;
-  DISALLOW_COPY_AND_ASSIGN(NavigateOperation);
-};
-
-class NavigateAnyOperation : public Operation {
- public:
-  NavigateAnyOperation() {}
-  ~NavigateAnyOperation() override {}
-  bool Execute(ExecutionContext* context) override {
-    const base::DictionaryValue* dict = NULL;
-    const base::ListValue* list = NULL;
-    if (context->current_node()->GetAsDictionary(&dict)) {
-      for (base::DictionaryValue::Iterator i(*dict);
-           !i.IsAtEnd(); i.Advance()) {
-        context->stack()->push_back(&i.value());
-        bool continue_traversal = context->ContinueExecution();
-        context->stack()->pop_back();
-        if (!continue_traversal)
-          return false;
-      }
-    } else if (context->current_node()->GetAsList(&list)) {
-      for (base::ListValue::const_iterator i = list->begin();
-           i != list->end(); ++i) {
-        context->stack()->push_back(*i);
-        bool continue_traversal = context->ContinueExecution();
-        context->stack()->pop_back();
-        if (!continue_traversal)
-          return false;
-      }
-    } else {
-      // Do nothing, just ignore this node.
-    }
-    return true;
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(NavigateAnyOperation);
-};
-
-class NavigateBackOperation : public Operation {
- public:
-  NavigateBackOperation() {}
-  ~NavigateBackOperation() override {}
-  bool Execute(ExecutionContext* context) override {
-    const base::Value* current_node = context->current_node();
-    context->stack()->pop_back();
-    bool continue_traversal = context->ContinueExecution();
-    context->stack()->push_back(current_node);
-    return continue_traversal;
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(NavigateBackOperation);
-};
-
-class StoreValue : public Operation {
- public:
-  StoreValue(const std::string& hashed_name, scoped_ptr<base::Value> value)
-      : hashed_name_(hashed_name),
-        value_(value.Pass()) {
-    DCHECK(base::IsStringUTF8(hashed_name));
-    DCHECK(value_);
-  }
-  ~StoreValue() override {}
-  bool Execute(ExecutionContext* context) override {
-    context->working_memory()->Set(hashed_name_, value_->DeepCopy());
-    return context->ContinueExecution();
-  }
-
- private:
-  std::string hashed_name_;
-  scoped_ptr<base::Value> value_;
-  DISALLOW_COPY_AND_ASSIGN(StoreValue);
-};
-
-class CompareStoredValue : public Operation {
- public:
-  CompareStoredValue(const std::string& hashed_name,
-                     scoped_ptr<base::Value> value,
-                     scoped_ptr<base::Value> default_value)
-      : hashed_name_(hashed_name),
-        value_(value.Pass()),
-        default_value_(default_value.Pass()) {
-    DCHECK(base::IsStringUTF8(hashed_name));
-    DCHECK(value_);
-    DCHECK(default_value_);
-  }
-  ~CompareStoredValue() override {}
-  bool Execute(ExecutionContext* context) override {
-    const base::Value* actual_value = NULL;
-    if (!context->working_memory()->Get(hashed_name_, &actual_value))
-      actual_value = default_value_.get();
-    if (!value_->Equals(actual_value))
-      return true;
-    return context->ContinueExecution();
-  }
-
- private:
-  std::string hashed_name_;
-  scoped_ptr<base::Value> value_;
-  scoped_ptr<base::Value> default_value_;
-  DISALLOW_COPY_AND_ASSIGN(CompareStoredValue);
-};
-
-template<bool ExpectedTypeIsBooleanNotHashable>
-class StoreNodeValue : public Operation {
- public:
-  explicit StoreNodeValue(const std::string& hashed_name)
-      : hashed_name_(hashed_name) {
-    DCHECK(base::IsStringUTF8(hashed_name));
-  }
-  ~StoreNodeValue() override {}
-  bool Execute(ExecutionContext* context) override {
-    scoped_ptr<base::Value> value;
-    if (ExpectedTypeIsBooleanNotHashable) {
-      if (!context->current_node()->IsType(base::Value::TYPE_BOOLEAN))
-        return true;
-      value.reset(context->current_node()->DeepCopy());
-    } else {
-      std::string hash;
-      if (!context->GetValueHash(*context->current_node(), &hash))
-        return true;
-      value.reset(new base::StringValue(hash));
-    }
-    context->working_memory()->Set(hashed_name_, value.release());
-    return context->ContinueExecution();
-  }
-
- private:
-  std::string hashed_name_;
-  DISALLOW_COPY_AND_ASSIGN(StoreNodeValue);
-};
-
-// Stores the hash of the registerable domain name -- as in, the portion of the
-// domain that is registerable, as opposed to controlled by a registrar; without
-// subdomains -- of the URL represented by the current node into working memory.
-class StoreNodeRegisterableDomain : public Operation {
- public:
-  explicit StoreNodeRegisterableDomain(const std::string& hashed_name)
-      : hashed_name_(hashed_name) {
-    DCHECK(base::IsStringUTF8(hashed_name));
-  }
-  ~StoreNodeRegisterableDomain() override {}
-  bool Execute(ExecutionContext* context) override {
-    std::string possibly_invalid_url;
-    std::string domain;
-    if (!context->current_node()->GetAsString(&possibly_invalid_url) ||
-        !GetRegisterableDomain(possibly_invalid_url, &domain))
-      return true;
-    context->working_memory()->Set(
-        hashed_name_, new base::StringValue(context->GetHash(domain)));
-    return context->ContinueExecution();
-  }
-
- private:
-  // If |possibly_invalid_url| is a valid URL having a registerable domain name
-  // part, outputs that in |registerable_domain| and returns true. Otherwise,
-  // returns false.
-  static bool GetRegisterableDomain(const std::string& possibly_invalid_url,
-                                    std::string* registerable_domain) {
-    namespace domains = net::registry_controlled_domains;
-    DCHECK(registerable_domain);
-    GURL url(possibly_invalid_url);
-    if (!url.is_valid())
-      return false;
-    std::string registry_plus_one = domains::GetDomainAndRegistry(
-        url.host(), domains::INCLUDE_PRIVATE_REGISTRIES);
-    size_t registry_length = domains::GetRegistryLength(
-        url.host(),
-        domains::INCLUDE_UNKNOWN_REGISTRIES,
-        domains::INCLUDE_PRIVATE_REGISTRIES);
-    // Fail unless (1.) the URL has a host part; and (2.) that host part is a
-    // well-formed domain name consisting of at least one subcomponent; followed
-    // by either a recognized registry identifier, or exactly one subcomponent,
-    // which is then assumed to be the unknown registry identifier.
-    if (registry_length == std::string::npos || registry_length == 0)
-      return false;
-    DCHECK_LT(registry_length, registry_plus_one.size());
-    // Subtract one to cut off the dot separating the SLD and the registry.
-    registerable_domain->assign(
-        registry_plus_one, 0, registry_plus_one.size() - registry_length - 1);
-    return true;
-  }
-
-  std::string hashed_name_;
-  DISALLOW_COPY_AND_ASSIGN(StoreNodeRegisterableDomain);
-};
-
-class CompareNodeBool : public Operation {
- public:
-  explicit CompareNodeBool(bool value) : value_(value) {}
-  ~CompareNodeBool() override {}
-  bool Execute(ExecutionContext* context) override {
-    bool actual_value = false;
-    if (!context->current_node()->GetAsBoolean(&actual_value))
-      return true;
-    if (actual_value != value_)
-      return true;
-    return context->ContinueExecution();
-  }
-
- private:
-  bool value_;
-  DISALLOW_COPY_AND_ASSIGN(CompareNodeBool);
-};
-
-class CompareNodeHash : public Operation {
- public:
-  explicit CompareNodeHash(const std::string& hashed_value)
-      : hashed_value_(hashed_value) {}
-  ~CompareNodeHash() override {}
-  bool Execute(ExecutionContext* context) override {
-    std::string actual_hash;
-    if (!context->GetValueHash(*context->current_node(), &actual_hash) ||
-        actual_hash != hashed_value_)
-      return true;
-    return context->ContinueExecution();
-  }
-
- private:
-  std::string hashed_value_;
-  DISALLOW_COPY_AND_ASSIGN(CompareNodeHash);
-};
-
-class CompareNodeHashNot : public Operation {
- public:
-  explicit CompareNodeHashNot(const std::string& hashed_value)
-      : hashed_value_(hashed_value) {}
-  ~CompareNodeHashNot() override {}
-  bool Execute(ExecutionContext* context) override {
-    std::string actual_hash;
-    if (context->GetValueHash(*context->current_node(), &actual_hash) &&
-        actual_hash == hashed_value_)
-      return true;
-    return context->ContinueExecution();
-  }
-
- private:
-  std::string hashed_value_;
-  DISALLOW_COPY_AND_ASSIGN(CompareNodeHashNot);
-};
-
-template<bool ExpectedTypeIsBooleanNotHashable>
-class CompareNodeToStored : public Operation {
- public:
-  explicit CompareNodeToStored(const std::string& hashed_name)
-      : hashed_name_(hashed_name) {}
-  ~CompareNodeToStored() override {}
-  bool Execute(ExecutionContext* context) override {
-    const base::Value* stored_value = NULL;
-    if (!context->working_memory()->Get(hashed_name_, &stored_value))
-      return true;
-    if (ExpectedTypeIsBooleanNotHashable) {
-      if (!context->current_node()->IsType(base::Value::TYPE_BOOLEAN) ||
-          !context->current_node()->Equals(stored_value))
-        return true;
-    } else {
-      std::string actual_hash;
-      std::string stored_hash;
-      if (!context->GetValueHash(*context->current_node(), &actual_hash) ||
-          !stored_value->GetAsString(&stored_hash) ||
-          actual_hash != stored_hash)
-        return true;
-    }
-    return context->ContinueExecution();
-  }
-
- private:
-  std::string hashed_name_;
-  DISALLOW_COPY_AND_ASSIGN(CompareNodeToStored);
-};
-
-class CompareNodeSubstring : public Operation {
- public:
-  explicit CompareNodeSubstring(const std::string& hashed_pattern,
-                                size_t pattern_length,
-                                uint32 pattern_sum)
-      : hashed_pattern_(hashed_pattern),
-        pattern_length_(pattern_length),
-        pattern_sum_(pattern_sum) {
-    DCHECK(pattern_length_);
-  }
-  ~CompareNodeSubstring() override {}
-  bool Execute(ExecutionContext* context) override {
-    std::string value_as_string;
-    if (!context->current_node()->GetAsString(&value_as_string) ||
-        !pattern_length_ || value_as_string.size() < pattern_length_)
-      return true;
-    // Go over the string with a sliding window. Meanwhile, maintain the sum in
-    // an incremental fashion, and only calculate the SHA-256 hash when the sum
-    // checks out so as to improve performance.
-    std::string::const_iterator window_begin = value_as_string.begin();
-    std::string::const_iterator window_end = window_begin + pattern_length_ - 1;
-    uint32 window_sum =
-        std::accumulate(window_begin, window_end, static_cast<uint32>(0u));
-    while (window_end != value_as_string.end()) {
-      window_sum += *window_end++;
-      if (window_sum == pattern_sum_ && context->GetHash(std::string(
-          window_begin, window_end)) == hashed_pattern_)
-        return context->ContinueExecution();
-      window_sum -= *window_begin++;
-    }
-    return true;
-  }
-
- private:
-  std::string hashed_pattern_;
-  size_t pattern_length_;
-  uint32 pattern_sum_;
-  DISALLOW_COPY_AND_ASSIGN(CompareNodeSubstring);
-};
-
-class StopExecutingSentenceOperation : public Operation {
- public:
-  StopExecutingSentenceOperation() {}
-  ~StopExecutingSentenceOperation() override {}
-  bool Execute(ExecutionContext* context) override { return false; }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(StopExecutingSentenceOperation);
-};
-
-class Parser {
- public:
-  explicit Parser(const std::string& program)
-      : program_(program),
-        next_instruction_index_(0u) {}
-  ~Parser() {}
-  bool ParseNextSentence(ScopedVector<Operation>* output) {
-    ScopedVector<Operation> operators;
-    bool sentence_ended = false;
-    while (next_instruction_index_ < program_.size() && !sentence_ended) {
-      uint8 op_code = 0;
-      if (!ReadOpCode(&op_code))
-        return false;
-      switch (static_cast<jtl_foundation::OpCodes>(op_code)) {
-        case jtl_foundation::NAVIGATE: {
-          std::string hashed_key;
-          if (!ReadHash(&hashed_key))
-            return false;
-          operators.push_back(new NavigateOperation(hashed_key));
-          break;
-        }
-        case jtl_foundation::NAVIGATE_ANY:
-          operators.push_back(new NavigateAnyOperation);
-          break;
-        case jtl_foundation::NAVIGATE_BACK:
-          operators.push_back(new NavigateBackOperation);
-          break;
-        case jtl_foundation::STORE_BOOL: {
-          std::string hashed_name;
-          if (!ReadHash(&hashed_name) || !base::IsStringUTF8(hashed_name))
-            return false;
-          bool value = false;
-          if (!ReadBool(&value))
-            return false;
-          operators.push_back(new StoreValue(
-              hashed_name,
-              scoped_ptr<base::Value>(new base::FundamentalValue(value))));
-          break;
-        }
-        case jtl_foundation::COMPARE_STORED_BOOL: {
-          std::string hashed_name;
-          if (!ReadHash(&hashed_name) || !base::IsStringUTF8(hashed_name))
-            return false;
-          bool value = false;
-          if (!ReadBool(&value))
-            return false;
-          bool default_value = false;
-          if (!ReadBool(&default_value))
-            return false;
-          operators.push_back(new CompareStoredValue(
-              hashed_name,
-              scoped_ptr<base::Value>(new base::FundamentalValue(value)),
-              scoped_ptr<base::Value>(
-                  new base::FundamentalValue(default_value))));
-          break;
-        }
-        case jtl_foundation::STORE_HASH: {
-          std::string hashed_name;
-          if (!ReadHash(&hashed_name) || !base::IsStringUTF8(hashed_name))
-            return false;
-          std::string hashed_value;
-          if (!ReadHash(&hashed_value))
-            return false;
-          operators.push_back(new StoreValue(
-              hashed_name,
-              scoped_ptr<base::Value>(new base::StringValue(hashed_value))));
-          break;
-        }
-        case jtl_foundation::COMPARE_STORED_HASH: {
-          std::string hashed_name;
-          if (!ReadHash(&hashed_name) || !base::IsStringUTF8(hashed_name))
-            return false;
-          std::string hashed_value;
-          if (!ReadHash(&hashed_value))
-            return false;
-          std::string hashed_default_value;
-          if (!ReadHash(&hashed_default_value))
-            return false;
-          operators.push_back(new CompareStoredValue(
-              hashed_name,
-              scoped_ptr<base::Value>(new base::StringValue(hashed_value)),
-              scoped_ptr<base::Value>(
-                  new base::StringValue(hashed_default_value))));
-          break;
-        }
-        case jtl_foundation::STORE_NODE_BOOL: {
-          std::string hashed_name;
-          if (!ReadHash(&hashed_name) || !base::IsStringUTF8(hashed_name))
-            return false;
-          operators.push_back(new StoreNodeValue<true>(hashed_name));
-          break;
-        }
-        case jtl_foundation::STORE_NODE_HASH: {
-          std::string hashed_name;
-          if (!ReadHash(&hashed_name) || !base::IsStringUTF8(hashed_name))
-            return false;
-          operators.push_back(new StoreNodeValue<false>(hashed_name));
-          break;
-        }
-        case jtl_foundation::STORE_NODE_REGISTERABLE_DOMAIN_HASH: {
-          std::string hashed_name;
-          if (!ReadHash(&hashed_name) || !base::IsStringUTF8(hashed_name))
-            return false;
-          operators.push_back(new StoreNodeRegisterableDomain(hashed_name));
-          break;
-        }
-        case jtl_foundation::COMPARE_NODE_BOOL: {
-          bool value = false;
-          if (!ReadBool(&value))
-            return false;
-          operators.push_back(new CompareNodeBool(value));
-          break;
-        }
-        case jtl_foundation::COMPARE_NODE_HASH: {
-          std::string hashed_value;
-          if (!ReadHash(&hashed_value))
-            return false;
-          operators.push_back(new CompareNodeHash(hashed_value));
-          break;
-        }
-        case jtl_foundation::COMPARE_NODE_HASH_NOT: {
-          std::string hashed_value;
-          if (!ReadHash(&hashed_value))
-            return false;
-          operators.push_back(new CompareNodeHashNot(hashed_value));
-          break;
-        }
-        case jtl_foundation::COMPARE_NODE_TO_STORED_BOOL: {
-          std::string hashed_name;
-          if (!ReadHash(&hashed_name) || !base::IsStringUTF8(hashed_name))
-            return false;
-          operators.push_back(new CompareNodeToStored<true>(hashed_name));
-          break;
-        }
-        case jtl_foundation::COMPARE_NODE_TO_STORED_HASH: {
-          std::string hashed_name;
-          if (!ReadHash(&hashed_name) || !base::IsStringUTF8(hashed_name))
-            return false;
-          operators.push_back(new CompareNodeToStored<false>(hashed_name));
-          break;
-        }
-        case jtl_foundation::COMPARE_NODE_SUBSTRING: {
-          std::string hashed_pattern;
-          uint32 pattern_length = 0, pattern_sum = 0;
-          if (!ReadHash(&hashed_pattern))
-            return false;
-          if (!ReadUint32(&pattern_length) || pattern_length == 0)
-            return false;
-          if (!ReadUint32(&pattern_sum))
-            return false;
-          operators.push_back(new CompareNodeSubstring(
-              hashed_pattern, pattern_length, pattern_sum));
-          break;
-        }
-        case jtl_foundation::STOP_EXECUTING_SENTENCE:
-          operators.push_back(new StopExecutingSentenceOperation);
-          break;
-        case jtl_foundation::END_OF_SENTENCE:
-          sentence_ended = true;
-          break;
-        default:
-          return false;
-      }
-    }
-    output->swap(operators);
-    return true;
-  }
-
-  bool HasNextSentence() const {
-    return next_instruction_index_ < program_.size();
-  }
-
- private:
-  // Reads an uint8 and returns whether this operation was successful.
-  bool ReadUint8(uint8* out) {
-    DCHECK(out);
-    if (next_instruction_index_ + 1u > program_.size())
-      return false;
-    *out = static_cast<uint8>(program_[next_instruction_index_]);
-    ++next_instruction_index_;
-    return true;
-  }
-
-  // Reads an uint32 and returns whether this operation was successful.
-  bool ReadUint32(uint32* out) {
-    DCHECK(out);
-    if (next_instruction_index_ + 4u > program_.size())
-      return false;
-    *out = 0u;
-    for (int i = 0; i < 4; ++i) {
-      *out >>= 8;
-      *out |= static_cast<uint8>(program_[next_instruction_index_]) << 24;
-      ++next_instruction_index_;
-    }
-    return true;
-  }
-
-  // Reads an operator code and returns whether this operation was successful.
-  bool ReadOpCode(uint8* out) { return ReadUint8(out); }
-
-  bool ReadHash(std::string* out) {
-    DCHECK(out);
-    if (next_instruction_index_ + jtl_foundation::kHashSizeInBytes >
-        program_.size())
-      return false;
-    *out = program_.substr(next_instruction_index_,
-                           jtl_foundation::kHashSizeInBytes);
-    next_instruction_index_ += jtl_foundation::kHashSizeInBytes;
-    DCHECK(jtl_foundation::Hasher::IsHash(*out));
-    return true;
-  }
-
-  bool ReadBool(bool* out) {
-    DCHECK(out);
-    uint8 value = 0;
-    if (!ReadUint8(&value))
-      return false;
-    if (value == 0)
-      *out = false;
-    else if (value == 1)
-      *out = true;
-    else
-      return false;
-    return true;
-  }
-
-  std::string program_;
-  size_t next_instruction_index_;
-  DISALLOW_COPY_AND_ASSIGN(Parser);
-};
-
-}  // namespace
-
-JtlInterpreter::JtlInterpreter(
-    const std::string& hasher_seed,
-    const std::string& program,
-    const base::DictionaryValue* input)
-    : hasher_seed_(hasher_seed),
-      program_(program),
-      input_(input),
-      working_memory_(new base::DictionaryValue),
-      result_(OK) {
-  DCHECK(input->IsType(base::Value::TYPE_DICTIONARY));
-}
-
-JtlInterpreter::~JtlInterpreter() {}
-
-void JtlInterpreter::Execute() {
-  jtl_foundation::Hasher hasher(hasher_seed_);
-  Parser parser(program_);
-  while (parser.HasNextSentence()) {
-    ScopedVector<Operation> sentence;
-    if (!parser.ParseNextSentence(&sentence)) {
-      result_ = PARSE_ERROR;
-      return;
-    }
-    ExecutionContext context(
-        &hasher, sentence.get(), input_, working_memory_.get());
-    context.ContinueExecution();
-    if (context.error()) {
-      result_ = RUNTIME_ERROR;
-      return;
-    }
-  }
-}
-
-bool JtlInterpreter::GetOutputBoolean(const std::string& unhashed_key,
-                                      bool* output) const {
-  std::string hashed_key =
-      jtl_foundation::Hasher(hasher_seed_).GetHash(unhashed_key);
-  return working_memory_->GetBoolean(hashed_key, output);
-}
-
-bool JtlInterpreter::GetOutputString(const std::string& unhashed_key,
-                                     std::string* output) const {
-  std::string hashed_key =
-      jtl_foundation::Hasher(hasher_seed_).GetHash(unhashed_key);
-  return working_memory_->GetString(hashed_key, output);
-}
-
-int JtlInterpreter::CalculateProgramChecksum() const {
-  uint8 digest[3] = {};
-  crypto::SHA256HashString(program_, digest, arraysize(digest));
-  return static_cast<uint32>(digest[0]) << 16 |
-         static_cast<uint32>(digest[1]) << 8 |
-         static_cast<uint32>(digest[2]);
-}
diff --git a/chrome/browser/profile_resetter/jtl_interpreter.h b/chrome/browser/profile_resetter/jtl_interpreter.h
deleted file mode 100644
index cafb7fd..0000000
--- a/chrome/browser/profile_resetter/jtl_interpreter.h
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_PROFILE_RESETTER_JTL_INTERPRETER_H_
-#define CHROME_BROWSER_PROFILE_RESETTER_JTL_INTERPRETER_H_
-
-#include <string>
-
-#include "base/basictypes.h"
-#include "base/values.h"
-
-// Executes a JTL program on a given dictionary.
-//
-// JTL (Json Traversal Language) programs are defined in jtl_foundation.h
-class JtlInterpreter {
- public:
-  enum Result {
-    OK,
-    PARSE_ERROR,
-    RUNTIME_ERROR,
-    RESULT_MAX,
-  };
-
-  // |hasher_seed| is a value used in jtl_foundation::Hasher. All node names,
-  // strings, integers and doubles are hashed before being compared to hash
-  // values listed in |program|.
-  // |program| is a byte array containing a JTL program.
-  // |input| is a dictionary on which the program is evaluated.
-  JtlInterpreter(const std::string& hasher_seed,
-                 const std::string& program,
-                 const base::DictionaryValue* input);
-  ~JtlInterpreter();
-
-  void Execute();
-
-  Result result() const { return result_; }
-  const base::DictionaryValue* working_memory() const {
-    return working_memory_.get();
-  }
-  bool GetOutputBoolean(const std::string& unhashed_key, bool* output) const;
-  bool GetOutputString(const std::string& unhashed_key,
-                       std::string* output) const;
-
-  // Generates a checksum of the loaded program, defined as the first 3 bytes of
-  // the program's SHA-256 hash interpreted as a big-endian integer.
-  int CalculateProgramChecksum() const;
-
- private:
-  // Input.
-  std::string hasher_seed_;
-  std::string program_;
-  const base::DictionaryValue* input_;
-  // Output.
-  scoped_ptr<base::DictionaryValue> working_memory_;
-  Result result_;
-
-  DISALLOW_COPY_AND_ASSIGN(JtlInterpreter);
-};
-
-#endif  // CHROME_BROWSER_PROFILE_RESETTER_JTL_INTERPRETER_H_
diff --git a/chrome/browser/profile_resetter/jtl_interpreter_unittest.cc b/chrome/browser/profile_resetter/jtl_interpreter_unittest.cc
deleted file mode 100644
index 8457264f..0000000
--- a/chrome/browser/profile_resetter/jtl_interpreter_unittest.cc
+++ /dev/null
@@ -1,689 +0,0 @@
-// Copyright 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/profile_resetter/jtl_interpreter.h"
-
-#include <numeric>
-
-#include "base/strings/string_util.h"
-#include "base/test/values_test_util.h"
-#include "chrome/browser/profile_resetter/jtl_foundation.h"
-#include "chrome/browser/profile_resetter/jtl_instructions.h"
-#include "crypto/hmac.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace {
-
-const char seed[] = "foobar";
-
-#define KEY_HASH_1 GetHash("KEY_HASH_1")
-#define KEY_HASH_2 GetHash("KEY_HASH_2")
-#define KEY_HASH_3 GetHash("KEY_HASH_3")
-#define KEY_HASH_4 GetHash("KEY_HASH_4")
-
-#define VALUE_HASH_1 GetHash("VALUE_HASH_1")
-#define VALUE_HASH_2 GetHash("VALUE_HASH_2")
-
-#define VAR_HASH_1 "01234567890123456789012345678901"
-#define VAR_HASH_2 "12345678901234567890123456789012"
-
-std::string GetHash(const std::string& input) {
-  return jtl_foundation::Hasher(seed).GetHash(input);
-}
-
-std::string EncodeUint32(uint32 value) {
-  std::string bytecode;
-  for (int i = 0; i < 4; ++i) {
-    bytecode.push_back(static_cast<char>(value & 0xFFu));
-    value >>= 8;
-  }
-  return bytecode;
-}
-
-// escaped_json_param may contain ' characters that are replaced with ". This
-// makes the code more readable because we need less escaping.
-#define INIT_INTERPRETER(program_param, escaped_json_param) \
-    const char* escaped_json = escaped_json_param; \
-    std::string json; \
-    base::ReplaceChars(escaped_json, "'", "\"", &json); \
-    scoped_ptr<base::Value> json_value(ParseJson(json)); \
-    JtlInterpreter interpreter( \
-        seed, \
-        program_param, \
-        static_cast<const base::DictionaryValue*>(json_value.get())); \
-    interpreter.Execute()
-
-using base::test::ParseJson;
-
-TEST(JtlInterpreter, Store) {
-  INIT_INTERPRETER(
-      OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE),
-      "{ 'KEY_HASH_1': 'VALUE_HASH_1' }");
-  EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
-  base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_1);
-}
-
-TEST(JtlInterpreter, NavigateAndStore) {
-  INIT_INTERPRETER(
-      OP_NAVIGATE(KEY_HASH_1) +
-      OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE),
-      "{ 'KEY_HASH_1': 'VALUE_HASH_1' }");
-  EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
-  base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_1);
-}
-
-TEST(JtlInterpreter, FailNavigate) {
-  INIT_INTERPRETER(
-      OP_NAVIGATE(KEY_HASH_2) +
-      OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE),
-      "{ 'KEY_HASH_1': 'VALUE_HASH_1' }");
-  EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
-  EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_1));
-}
-
-TEST(JtlInterpreter, ConsecutiveNavigate) {
-  INIT_INTERPRETER(
-      OP_NAVIGATE(KEY_HASH_1) +
-      OP_NAVIGATE(KEY_HASH_2) +
-      OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE),
-      "{ 'KEY_HASH_1': { 'KEY_HASH_2': 'VALUE_HASH_1' } }");
-  EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
-  base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_1);
-}
-
-TEST(JtlInterpreter, FailConsecutiveNavigate) {
-  INIT_INTERPRETER(
-      OP_NAVIGATE(KEY_HASH_1) +
-      OP_NAVIGATE(KEY_HASH_2) +
-      OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE),
-      "{ 'KEY_HASH_1': 'foo' }");
-  EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
-  EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_1));
-}
-
-TEST(JtlInterpreter, NavigateAnyInDictionary) {
-  INIT_INTERPRETER(
-      OP_NAVIGATE(KEY_HASH_1) +
-      OP_NAVIGATE_ANY +
-      OP_NAVIGATE(KEY_HASH_4) +
-      OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE),
-          "{ 'KEY_HASH_1':"
-          "  { 'KEY_HASH_2': {'KEY_HASH_3': 'VALUE_HASH_1' },"
-          "    'KEY_HASH_3': {'KEY_HASH_4': 'VALUE_HASH_1' }"
-          "  } }");
-  EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
-  base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_1);
-}
-
-TEST(JtlInterpreter, NavigateAnyInList) {
-  INIT_INTERPRETER(
-      OP_NAVIGATE(KEY_HASH_1) +
-      OP_NAVIGATE_ANY +
-      OP_NAVIGATE(KEY_HASH_4) +
-      OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE),
-          "{ 'KEY_HASH_1':"
-          "  [ {'KEY_HASH_3': 'VALUE_HASH_1' },"
-          "    {'KEY_HASH_4': 'VALUE_HASH_1' }"
-          "  ] }");
-  EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
-  base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_1);
-}
-
-TEST(JtlInterpreter, NavigateBack) {
-  INIT_INTERPRETER(
-      OP_NAVIGATE(KEY_HASH_1) +
-      OP_NAVIGATE(KEY_HASH_2) +
-      OP_NAVIGATE_BACK +
-      OP_NAVIGATE(KEY_HASH_3) +
-      OP_NAVIGATE(KEY_HASH_4) +
-      OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE),
-          "{ 'KEY_HASH_1':"
-          "  { 'KEY_HASH_2': {'KEY_HASH_3': 'VALUE_HASH_1' },"
-          "    'KEY_HASH_3': {'KEY_HASH_4': 'VALUE_HASH_1' }"
-          "  } }");
-  EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
-  base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_1);
-}
-
-TEST(JtlInterpreter, StoreTwoValues) {
-  INIT_INTERPRETER(
-      OP_NAVIGATE(KEY_HASH_1) +
-      OP_NAVIGATE(KEY_HASH_2) +
-      OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE) +
-      OP_STORE_HASH(VAR_HASH_2, VALUE_HASH_1),
-      "{ 'KEY_HASH_1': { 'KEY_HASH_2': 'VALUE_HASH_1' } }");
-  EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
-  base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_1);
-  base::ExpectDictStringValue(VALUE_HASH_1, *interpreter.working_memory(),
-                              VAR_HASH_2);
-}
-
-TEST(JtlInterpreter, CompareStoredMatch) {
-  INIT_INTERPRETER(
-      OP_NAVIGATE(KEY_HASH_1) +
-      OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE) +
-      OP_NAVIGATE(KEY_HASH_2) +
-      OP_COMPARE_STORED_BOOL(VAR_HASH_1, VALUE_TRUE, VALUE_FALSE) +
-      OP_STORE_BOOL(VAR_HASH_2, VALUE_TRUE),
-      "{ 'KEY_HASH_1': { 'KEY_HASH_2': 'VALUE_HASH_1' } }");
-  EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
-  base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_1);
-  base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_2);
-}
-
-TEST(JtlInterpreter, CompareStoredMismatch) {
-  INIT_INTERPRETER(
-      OP_NAVIGATE(KEY_HASH_1) +
-      OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE) +
-      OP_NAVIGATE(KEY_HASH_2) +
-      OP_COMPARE_STORED_BOOL(VAR_HASH_1, VALUE_FALSE, VALUE_TRUE) +
-      OP_STORE_BOOL(VAR_HASH_2, VALUE_TRUE),
-      "{ 'KEY_HASH_1': { 'KEY_HASH_2': 'VALUE_HASH_1' } }");
-  EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
-  base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_1);
-  EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_2));
-}
-
-TEST(JtlInterpreter, CompareStoredNoValueMatchingDefault) {
-  INIT_INTERPRETER(
-      OP_NAVIGATE(KEY_HASH_1) +
-      OP_NAVIGATE(KEY_HASH_2) +
-      OP_COMPARE_STORED_BOOL(VAR_HASH_1, VALUE_TRUE, VALUE_TRUE) +
-      OP_STORE_BOOL(VAR_HASH_2, VALUE_TRUE),
-      "{ 'KEY_HASH_1': { 'KEY_HASH_2': 'VALUE_HASH_1' } }");
-  EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
-  base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_2);
-}
-
-TEST(JtlInterpreter, CompareStoredNoValueMismatchingDefault) {
-  INIT_INTERPRETER(
-      OP_NAVIGATE(KEY_HASH_1) +
-      OP_NAVIGATE(KEY_HASH_2) +
-      OP_COMPARE_STORED_BOOL(VAR_HASH_1, VALUE_TRUE, VALUE_FALSE) +
-      OP_STORE_BOOL(VAR_HASH_2, VALUE_TRUE),
-      "{ 'KEY_HASH_1': { 'KEY_HASH_2': 'VALUE_HASH_1' } }");
-  EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
-  EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_2));
-}
-
-TEST(JtlInterpreter, CompareBool) {
-  struct TestCase {
-    std::string expected_value;
-    const char* json;
-    bool expected_success;
-  } cases[] = {
-    { VALUE_TRUE, "{ 'KEY_HASH_1': true }", true },
-    { VALUE_FALSE, "{ 'KEY_HASH_1': false }", true },
-    { VALUE_TRUE, "{ 'KEY_HASH_1': false }", false },
-    { VALUE_TRUE, "{ 'KEY_HASH_1': 'abc' }", false },
-    { VALUE_TRUE, "{ 'KEY_HASH_1': 1 }", false },
-    { VALUE_TRUE, "{ 'KEY_HASH_1': 1.2 }", false },
-    { VALUE_TRUE, "{ 'KEY_HASH_1': [1] }", false },
-    { VALUE_TRUE, "{ 'KEY_HASH_1': {'a': 'b'} }", false },
-  };
-
-  for (size_t i = 0; i < arraysize(cases); ++i) {
-    SCOPED_TRACE(testing::Message() << "Iteration " << i);
-    INIT_INTERPRETER(
-        OP_NAVIGATE(KEY_HASH_1) +
-        OP_COMPARE_NODE_BOOL(cases[i].expected_value) +
-        OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE),
-        cases[i].json);
-    EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
-    if (cases[i].expected_success) {
-      base::ExpectDictBooleanValue(
-          true, *interpreter.working_memory(), VAR_HASH_1);
-    } else {
-      EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_1));
-    }
-  }
-}
-
-TEST(JtlInterpreter, CompareHashString) {
-  struct TestCase {
-    std::string expected_value;
-    const char* json;
-    bool expected_success;
-  } cases[] = {
-    { VALUE_HASH_1, "{ 'KEY_HASH_1': 'VALUE_HASH_1' }", true },
-    { VALUE_HASH_1, "{ 'KEY_HASH_1': 'VALUE_HASH_2' }", false },
-    { VALUE_HASH_1, "{ 'KEY_HASH_1': true }", false },
-    { VALUE_HASH_1, "{ 'KEY_HASH_1': 1 }", false },
-    { VALUE_HASH_1, "{ 'KEY_HASH_1': 1.1 }", false },
-    { VALUE_HASH_1, "{ 'KEY_HASH_1': [1] }", false },
-    { VALUE_HASH_1, "{ 'KEY_HASH_1': {'a': 'b'} }", false },
-
-    { GetHash("1.2"), "{ 'KEY_HASH_1': 1.2 }", true },
-    { GetHash("1.2"), "{ 'KEY_HASH_1': 'VALUE_HASH_1' }", false },
-    { GetHash("1.2"), "{ 'KEY_HASH_1': true }", false },
-    { GetHash("1.2"), "{ 'KEY_HASH_1': 1 }", false },
-    { GetHash("1.2"), "{ 'KEY_HASH_1': 1.3 }", false },
-    { GetHash("1.2"), "{ 'KEY_HASH_1': [1] }", false },
-    { GetHash("1.2"), "{ 'KEY_HASH_1': {'a': 'b'} }", false },
-
-    { GetHash("1"), "{ 'KEY_HASH_1': 1 }", true },
-    { GetHash("1"), "{ 'KEY_HASH_1': 'VALUE_HASH_1' }", false },
-    { GetHash("1"), "{ 'KEY_HASH_1': true }", false },
-    { GetHash("1"), "{ 'KEY_HASH_1': 2 }", false },
-    { GetHash("1"), "{ 'KEY_HASH_1': 1.1 }", false },
-    { GetHash("1"), "{ 'KEY_HASH_1': [1] }", false },
-    { GetHash("1"), "{ 'KEY_HASH_1': {'a': 'b'} }", false },
-  };
-
-  for (size_t i = 0; i < arraysize(cases); ++i) {
-    SCOPED_TRACE(testing::Message() << "Iteration " << i);
-    INIT_INTERPRETER(
-        OP_NAVIGATE(KEY_HASH_1) +
-        OP_COMPARE_NODE_HASH(cases[i].expected_value) +
-        OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE),
-        cases[i].json);
-    EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
-    if (cases[i].expected_success) {
-      base::ExpectDictBooleanValue(
-          true, *interpreter.working_memory(), VAR_HASH_1);
-    } else {
-      EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_1));
-    }
-  }
-
-  for (size_t i = 0; i < arraysize(cases); ++i) {
-    SCOPED_TRACE(testing::Message() << "Negated, Iteration " << i);
-    INIT_INTERPRETER(
-        OP_NAVIGATE(KEY_HASH_1) +
-        OP_COMPARE_NODE_HASH_NOT(cases[i].expected_value) +
-        OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE),
-        cases[i].json);
-    EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
-    if (!cases[i].expected_success) {
-      base::ExpectDictBooleanValue(
-          true, *interpreter.working_memory(), VAR_HASH_1);
-    } else {
-      EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_1));
-    }
-  }
-}
-
-TEST(JtlInterpreter, StoreNodeBool) {
-  struct TestCase {
-    bool expected_value;
-    const char* json;
-    bool expected_success;
-  } cases[] = {
-    { true, "{ 'KEY_HASH_1': true }", true },
-    { false, "{ 'KEY_HASH_1': false }", true },
-    { false, "{ 'KEY_HASH_1': 'abc' }", false },
-    { false, "{ 'KEY_HASH_1': 1 }", false },
-    { false, "{ 'KEY_HASH_1': 1.2 }", false },
-    { false, "{ 'KEY_HASH_1': [1] }", false },
-    { false, "{ 'KEY_HASH_1': {'a': 'b'} }", false },
-  };
-
-  for (size_t i = 0; i < arraysize(cases); ++i) {
-    SCOPED_TRACE(testing::Message() << "Iteration " << i);
-    INIT_INTERPRETER(
-        OP_NAVIGATE(KEY_HASH_1) +
-        OP_STORE_NODE_BOOL(VAR_HASH_1) +
-        OP_STORE_BOOL(VAR_HASH_2, VALUE_TRUE),
-        cases[i].json);
-    EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
-    if (cases[i].expected_success) {
-      base::ExpectDictBooleanValue(
-          cases[i].expected_value, *interpreter.working_memory(), VAR_HASH_1);
-      base::ExpectDictBooleanValue(
-          true, *interpreter.working_memory(), VAR_HASH_2);
-    } else {
-      EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_1));
-      EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_2));
-    }
-  }
-}
-
-TEST(JtlInterpreter, CompareNodeToStoredBool) {
-  struct TestCase {
-    std::string stored_value;
-    const char* json;
-    bool expected_success;
-  } cases[] = {
-    { VALUE_TRUE, "{ 'KEY_HASH_1': true }", true },
-    { VALUE_FALSE, "{ 'KEY_HASH_1': false }", true },
-    { VALUE_FALSE, "{ 'KEY_HASH_1': true }", false },
-    { std::string(), "{ 'KEY_HASH_1': true }", false },
-
-    { VALUE_HASH_1, "{ 'KEY_HASH_1': 'VALUE_HASH_1' }", false },
-    { GetHash("1"), "{ 'KEY_HASH_1': 1 }", false },
-    { GetHash("1.2"), "{ 'KEY_HASH_1': 1.2 }", false },
-
-    { VALUE_HASH_1, "{ 'KEY_HASH_1': true }", false },
-    { GetHash("1"), "{ 'KEY_HASH_1': true }", false },
-    { GetHash("1.2"), "{ 'KEY_HASH_1': true }", false },
-
-    { VALUE_TRUE, "{ 'KEY_HASH_1': 'VALUE_HASH_1' }", false },
-    { VALUE_TRUE, "{ 'KEY_HASH_1': 1 }", false },
-    { VALUE_TRUE, "{ 'KEY_HASH_1': 1.2 }", false },
-    { VALUE_TRUE, "{ 'KEY_HASH_1': [1] }", false },
-    { VALUE_TRUE, "{ 'KEY_HASH_1': {'a': 'b'} }", false },
-  };
-
-  for (size_t i = 0; i < arraysize(cases); ++i) {
-    SCOPED_TRACE(testing::Message() << "Iteration " << i);
-    std::string store_op;
-    if (cases[i].stored_value == VALUE_TRUE ||
-        cases[i].stored_value == VALUE_FALSE)
-      store_op = OP_STORE_BOOL(VAR_HASH_1, cases[i].stored_value);
-    else if (!cases[i].stored_value.empty())
-      store_op = OP_STORE_HASH(VAR_HASH_1, cases[i].stored_value);
-    INIT_INTERPRETER(
-        store_op +
-        OP_NAVIGATE(KEY_HASH_1) +
-        OP_COMPARE_NODE_TO_STORED_BOOL(VAR_HASH_1) +
-        OP_STORE_BOOL(VAR_HASH_2, VALUE_TRUE),
-        cases[i].json);
-    EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
-    if (cases[i].expected_success) {
-      base::ExpectDictBooleanValue(
-          true, *interpreter.working_memory(), VAR_HASH_2);
-    } else {
-      EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_2));
-    }
-  }
-}
-
-TEST(JtlInterpreter, StoreNodeHash) {
-  struct TestCase {
-    std::string expected_value;
-    const char* json;
-    bool expected_success;
-  } cases[] = {
-    { VALUE_HASH_1, "{ 'KEY_HASH_1': 'VALUE_HASH_1' }", true },
-    { VALUE_HASH_2, "{ 'KEY_HASH_1': 'VALUE_HASH_2' }", true },
-    { GetHash("1"), "{ 'KEY_HASH_1': 1 }", true },
-    { GetHash("1.2"), "{ 'KEY_HASH_1': 1.2 }", true },
-    { std::string(), "{ 'KEY_HASH_1': true }", false },
-    { std::string(), "{ 'KEY_HASH_1': [1] }", false },
-    { std::string(), "{ 'KEY_HASH_1': {'a': 'b'} }", false },
-  };
-
-  for (size_t i = 0; i < arraysize(cases); ++i) {
-    SCOPED_TRACE(testing::Message() << "Iteration " << i);
-    INIT_INTERPRETER(
-        OP_NAVIGATE(KEY_HASH_1) +
-        OP_STORE_NODE_HASH(VAR_HASH_1) +
-        OP_STORE_BOOL(VAR_HASH_2, VALUE_TRUE),
-        cases[i].json);
-    EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
-    if (cases[i].expected_success) {
-      base::ExpectDictStringValue(
-          cases[i].expected_value, *interpreter.working_memory(), VAR_HASH_1);
-      base::ExpectDictBooleanValue(
-          true, *interpreter.working_memory(), VAR_HASH_2);
-    } else {
-      EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_1));
-      EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_2));
-    }
-  }
-}
-
-TEST(JtlInterpreter, CompareNodeToStoredHash) {
-  struct TestCase {
-    std::string stored_value;
-    const char* json;
-    bool expected_success;
-  } cases[] = {
-    { VALUE_HASH_1, "{ 'KEY_HASH_1': 'VALUE_HASH_1' }", true },
-    { VALUE_HASH_2, "{ 'KEY_HASH_1': 'VALUE_HASH_2' }", true },
-    { std::string(), "{ 'KEY_HASH_1': 'VALUE_HASH_2' }", false },
-    { VALUE_HASH_1, "{ 'KEY_HASH_1': 'VALUE_HASH_2' }", false },
-    { VALUE_HASH_1, "{ 'KEY_HASH_1': true }", false },
-    { VALUE_HASH_1, "{ 'KEY_HASH_1': 1 }", false },
-    { VALUE_HASH_1, "{ 'KEY_HASH_1': 1.1 }", false },
-    { VALUE_HASH_1, "{ 'KEY_HASH_1': [1] }", false },
-    { VALUE_HASH_1, "{ 'KEY_HASH_1': {'a': 'b'} }", false },
-
-    { GetHash("1.2"), "{ 'KEY_HASH_1': 1.2 }", true },
-    { GetHash("1.3"), "{ 'KEY_HASH_1': 1.3 }", true },
-    { std::string(), "{ 'KEY_HASH_1': 1.2 }", false },
-    { GetHash("1.2"), "{ 'KEY_HASH_1': 'VALUE_HASH_1' }", false },
-    { GetHash("1.2"), "{ 'KEY_HASH_1': true }", false },
-    { GetHash("1.2"), "{ 'KEY_HASH_1': 1 }", false },
-    { GetHash("1.2"), "{ 'KEY_HASH_1': 1.3 }", false },
-    { GetHash("1.2"), "{ 'KEY_HASH_1': [1] }", false },
-    { GetHash("1.2"), "{ 'KEY_HASH_1': {'a': 'b'} }", false },
-
-    { GetHash("1"), "{ 'KEY_HASH_1': 1 }", true },
-    { GetHash("2"), "{ 'KEY_HASH_1': 2 }", true },
-    { std::string(), "{ 'KEY_HASH_1': 2 }", false },
-    { GetHash("1"), "{ 'KEY_HASH_1': 'VALUE_HASH_1' }", false },
-    { GetHash("1"), "{ 'KEY_HASH_1': true }", false },
-    { GetHash("1"), "{ 'KEY_HASH_1': 2 }", false },
-    { GetHash("1"), "{ 'KEY_HASH_1': 1.1 }", false },
-    { GetHash("1"), "{ 'KEY_HASH_1': [1] }", false },
-    { GetHash("1"), "{ 'KEY_HASH_1': {'a': 'b'} }", false },
-
-    { VALUE_TRUE, "{ 'KEY_HASH_1': 'VALUE_HASH_1' }", false },
-    { VALUE_TRUE, "{ 'KEY_HASH_1': 1 }", false },
-    { VALUE_TRUE, "{ 'KEY_HASH_1': 1.3 }", false },
-    { VALUE_TRUE, "{ 'KEY_HASH_1': [1] }", false },
-    { VALUE_TRUE, "{ 'KEY_HASH_1': {'a': 'b'} }", false },
-
-    { VALUE_TRUE, "{ 'KEY_HASH_1': true }", false },
-    { VALUE_FALSE, "{ 'KEY_HASH_1': false }", false },
-  };
-
-  for (size_t i = 0; i < arraysize(cases); ++i) {
-    SCOPED_TRACE(testing::Message() << "Iteration " << i);
-    std::string store_op;
-    if (cases[i].stored_value == VALUE_TRUE ||
-        cases[i].stored_value == VALUE_FALSE)
-      store_op = OP_STORE_BOOL(VAR_HASH_1, cases[i].stored_value);
-    else if (!cases[i].stored_value.empty())
-      store_op = OP_STORE_HASH(VAR_HASH_1, cases[i].stored_value);
-    INIT_INTERPRETER(
-        store_op +
-        OP_NAVIGATE(KEY_HASH_1) +
-        OP_COMPARE_NODE_TO_STORED_HASH(VAR_HASH_1) +
-        OP_STORE_BOOL(VAR_HASH_2, VALUE_TRUE),
-        cases[i].json);
-    EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
-    if (cases[i].expected_success) {
-      base::ExpectDictBooleanValue(
-          true, *interpreter.working_memory(), VAR_HASH_2);
-    } else {
-      EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_2));
-    }
-  }
-}
-
-TEST(JtlInterpreter, CompareSubstring) {
-  struct TestCase {
-    std::string pattern;
-    const char* json;
-    bool expected_success;
-  } cases[] = {
-    { "abc", "{ 'KEY_HASH_1': 'abcdefghijklmnopqrstuvwxyz' }", true },
-    { "xyz", "{ 'KEY_HASH_1': 'abcdefghijklmnopqrstuvwxyz' }", true },
-    { "m", "{ 'KEY_HASH_1': 'abcdefghijklmnopqrstuvwxyz' }", true },
-    { "abc", "{ 'KEY_HASH_1': 'abc' }", true },
-    { "cba", "{ 'KEY_HASH_1': 'abcdefghijklmnopqrstuvwxyz' }", false },
-    { "acd", "{ 'KEY_HASH_1': 'abcdefghijklmnopqrstuvwxyz' }", false },
-    { "waaaaaaay_too_long", "{ 'KEY_HASH_1': 'abc' }", false },
-
-    { VALUE_HASH_1, "{ 'KEY_HASH_1': true }", false },
-    { VALUE_HASH_1, "{ 'KEY_HASH_1': 1 }", false },
-    { VALUE_HASH_1, "{ 'KEY_HASH_1': 1.1 }", false },
-    { VALUE_HASH_1, "{ 'KEY_HASH_1': [1] }", false },
-    { VALUE_HASH_1, "{ 'KEY_HASH_1': {'a': 'b'} }", false },
-  };
-
-  for (size_t i = 0; i < arraysize(cases); ++i) {
-    SCOPED_TRACE(testing::Message() << "Iteration " << i);
-    std::string pattern = cases[i].pattern;
-    uint32 pattern_sum = std::accumulate(
-        pattern.begin(), pattern.end(), static_cast<uint32>(0u));
-    INIT_INTERPRETER(
-        OP_NAVIGATE(KEY_HASH_1) +
-        OP_COMPARE_NODE_SUBSTRING(GetHash(pattern),
-                                  EncodeUint32(pattern.size()),
-                                  EncodeUint32(pattern_sum)) +
-        OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE),
-        cases[i].json);
-    EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
-    if (cases[i].expected_success) {
-      base::ExpectDictBooleanValue(
-          true, *interpreter.working_memory(), VAR_HASH_1);
-    } else {
-      EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_1));
-    }
-  }
-}
-
-TEST(JtlInterpreter, StoreNodeRegisterableDomainHash) {
-  struct TestCase {
-    std::string expected_value;
-    const char* json;
-    bool expected_success;
-  } cases[] = {
-    { GetHash("google"), "{ 'KEY_HASH_1': 'http://google.com/path' }", true },
-    { GetHash("google"), "{ 'KEY_HASH_1': 'http://mail.google.com/' }", true },
-    { GetHash("google"), "{ 'KEY_HASH_1': 'http://google.co.uk/' }", true },
-    { GetHash("google"), "{ 'KEY_HASH_1': 'http://google.com./' }", true },
-    { GetHash("google"), "{ 'KEY_HASH_1': 'http://..google.com/' }", true },
-
-    { GetHash("foo"), "{ 'KEY_HASH_1': 'http://foo.bar/path' }", true },
-    { GetHash("foo"), "{ 'KEY_HASH_1': 'http://sub.foo.bar' }", true },
-    { GetHash("foo"), "{ 'KEY_HASH_1': 'http://foo.appspot.com/' }", true },
-    { GetHash("foo"), "{ 'KEY_HASH_1': 'http://sub.foo.appspot.com' }", true },
-
-    { std::string(), "{ 'KEY_HASH_1': 'http://google.com../' }", false },
-
-    { std::string(), "{ 'KEY_HASH_1': 'http://bar/path' }", false },
-    { std::string(), "{ 'KEY_HASH_1': 'http://co.uk/path' }", false },
-    { std::string(), "{ 'KEY_HASH_1': 'http://appspot.com/path' }", false },
-    { std::string(), "{ 'KEY_HASH_1': 'http://127.0.0.1/path' }", false },
-    { std::string(), "{ 'KEY_HASH_1': 'file:///C:/bar.html' }", false },
-
-    { std::string(), "{ 'KEY_HASH_1': 1 }", false },
-    { std::string(), "{ 'KEY_HASH_1': 1.2 }", false },
-    { std::string(), "{ 'KEY_HASH_1': true }", false },
-    { std::string(), "{ 'KEY_HASH_1': [1] }", false },
-    { std::string(), "{ 'KEY_HASH_1': {'a': 'b'} }", false },
-  };
-
-  for (size_t i = 0; i < arraysize(cases); ++i) {
-    SCOPED_TRACE(testing::Message() << "Iteration " << i);
-    INIT_INTERPRETER(
-        OP_NAVIGATE(KEY_HASH_1) +
-        OP_STORE_NODE_REGISTERABLE_DOMAIN_HASH(VAR_HASH_1) +
-        OP_STORE_BOOL(VAR_HASH_2, VALUE_TRUE),
-        cases[i].json);
-    EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
-    if (cases[i].expected_success) {
-      base::ExpectDictStringValue(
-          cases[i].expected_value, *interpreter.working_memory(), VAR_HASH_1);
-      base::ExpectDictBooleanValue(
-          true, *interpreter.working_memory(), VAR_HASH_2);
-    } else {
-      EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_1));
-      EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_2));
-    }
-  }
-}
-
-TEST(JtlInterpreter, Stop) {
-  INIT_INTERPRETER(
-      OP_NAVIGATE(KEY_HASH_1) +
-      OP_NAVIGATE(KEY_HASH_2) +
-      OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE) +
-      OP_STOP_EXECUTING_SENTENCE +
-      OP_STORE_BOOL(VAR_HASH_2, VALUE_TRUE),
-      "{ 'KEY_HASH_1': { 'KEY_HASH_2': 'VALUE_HASH_1' } }");
-  EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
-  base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_1);
-  EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_2));
-}
-
-TEST(JtlInterpreter, EndOfSentence) {
-  INIT_INTERPRETER(
-      OP_NAVIGATE(KEY_HASH_1) +
-      OP_NAVIGATE(KEY_HASH_2) +
-      OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE) +
-      OP_END_OF_SENTENCE +
-      OP_STORE_BOOL(VAR_HASH_2, VALUE_TRUE),
-      "{ 'KEY_HASH_1': { 'KEY_HASH_2': 'VALUE_HASH_1' } }");
-  EXPECT_EQ(JtlInterpreter::OK, interpreter.result());
-  base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_1);
-  base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_2);
-}
-
-TEST(JtlInterpreter, InvalidBack) {
-  INIT_INTERPRETER(
-      OP_NAVIGATE(KEY_HASH_1) +
-      OP_NAVIGATE_BACK +
-      OP_NAVIGATE_BACK,
-      "{ 'KEY_HASH_1': { 'KEY_HASH_2': 'VALUE_HASH_1' } }");
-  EXPECT_EQ(JtlInterpreter::RUNTIME_ERROR, interpreter.result());
-}
-
-TEST(JtlInterpreter, IncorrectPrograms) {
-  std::string missing_hash;
-  std::string missing_bool;
-  std::string invalid_hash("123");
-  std::string invalid_bool("\x02", 1);
-  std::string invalid_operation("\x99", 1);
-  std::string programs[] = {
-    OP_NAVIGATE(missing_hash),
-    OP_NAVIGATE(invalid_hash),
-    OP_STORE_BOOL(VAR_HASH_1, invalid_bool),
-    OP_STORE_BOOL(missing_hash, VALUE_TRUE),
-    OP_STORE_BOOL(invalid_hash, VALUE_TRUE),
-    OP_COMPARE_STORED_BOOL(invalid_hash, VALUE_TRUE, VALUE_TRUE),
-    OP_COMPARE_STORED_BOOL(VAR_HASH_1, invalid_bool, VALUE_TRUE),
-    OP_COMPARE_STORED_BOOL(VAR_HASH_1, VALUE_TRUE, invalid_bool),
-    OP_COMPARE_STORED_BOOL(VAR_HASH_1, VALUE_TRUE, missing_bool),
-    OP_STORE_NODE_BOOL(missing_hash),
-    OP_STORE_NODE_BOOL(invalid_hash),
-    OP_STORE_NODE_HASH(missing_hash),
-    OP_STORE_NODE_HASH(invalid_hash),
-    OP_COMPARE_NODE_BOOL(missing_bool),
-    OP_COMPARE_NODE_BOOL(invalid_bool),
-    OP_COMPARE_NODE_HASH(missing_hash),
-    OP_COMPARE_NODE_HASH(invalid_hash),
-    OP_COMPARE_NODE_TO_STORED_BOOL(missing_hash),
-    OP_COMPARE_NODE_TO_STORED_BOOL(invalid_hash),
-    OP_COMPARE_NODE_TO_STORED_HASH(missing_hash),
-    OP_COMPARE_NODE_TO_STORED_HASH(invalid_hash),
-    invalid_operation,
-  };
-  for (size_t i = 0; i < arraysize(programs); ++i) {
-    SCOPED_TRACE(testing::Message() << "Iteration " << i);
-    INIT_INTERPRETER(programs[i],
-                     "{ 'KEY_HASH_1': { 'KEY_HASH_2': 'VALUE_HASH_1' } }");
-    EXPECT_EQ(JtlInterpreter::PARSE_ERROR, interpreter.result());
-  }
-}
-
-TEST(JtlInterpreter, GetOutput) {
-  INIT_INTERPRETER(
-      OP_STORE_BOOL(GetHash("output1"), VALUE_TRUE) +
-      OP_STORE_HASH(GetHash("output2"), VALUE_HASH_1),
-      "{}");
-  bool output1 = false;
-  std::string output2;
-  EXPECT_TRUE(interpreter.GetOutputBoolean("output1", &output1));
-  EXPECT_EQ(true, output1);
-  EXPECT_TRUE(interpreter.GetOutputString("output2", &output2));
-  EXPECT_EQ(VALUE_HASH_1, output2);
-  EXPECT_FALSE(interpreter.GetOutputBoolean("outputxx", &output1));
-  EXPECT_FALSE(interpreter.GetOutputString("outputxx", &output2));
-}
-
-TEST(JtlInterpreter, CalculateProgramChecksum) {
-  const char kTestSeed[] = "Irrelevant seed value.";
-  const char kTestProgram[] = "The quick brown fox jumps over the lazy dog.";
-  // This program is invalid, but we are not actually executing it.
-  base::DictionaryValue input;
-  JtlInterpreter interpreter(kTestSeed, kTestProgram, &input);
-  EXPECT_EQ(0xef537f, interpreter.CalculateProgramChecksum());
-}
-
-}  // namespace
diff --git a/chrome/browser/profile_resetter/profile_reset_global_error.cc b/chrome/browser/profile_resetter/profile_reset_global_error.cc
deleted file mode 100644
index a355b642..0000000
--- a/chrome/browser/profile_resetter/profile_reset_global_error.cc
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/profile_resetter/profile_reset_global_error.h"
-
-#include "base/metrics/histogram.h"
-#include "chrome/app/chrome_command_ids.h"
-#include "chrome/browser/profile_resetter/automatic_profile_resetter.h"
-#include "chrome/browser/profile_resetter/automatic_profile_resetter_factory.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/browser_window.h"
-#include "chrome/browser/ui/chrome_pages.h"
-#include "chrome/browser/ui/global_error/global_error_service.h"
-#include "chrome/browser/ui/global_error/global_error_service_factory.h"
-#include "chrome/common/url_constants.h"
-#include "grit/chromium_strings.h"
-#include "grit/generated_resources.h"
-#include "ui/base/l10n/l10n_util.h"
-
-namespace {
-
-base::TimeDelta GetPromptDelayHistogramMaximum() {
-  return base::TimeDelta::FromDays(7);
-}
-
-// Records the delay between when the reset prompt is triggered and when the
-// bubble can actually be shown.
-void RecordPromptDelay(const base::TimeDelta& delay) {
-  UMA_HISTOGRAM_CUSTOM_TIMES(
-      "AutomaticProfileReset.PromptDelay", delay,
-      base::TimeDelta::FromSeconds(1), GetPromptDelayHistogramMaximum(), 50);
-}
-
-}  // namespace
-
-
-// ProfileResetGlobalError ---------------------------------------------------
-
-ProfileResetGlobalError::ProfileResetGlobalError(Profile* profile)
-    : profile_(profile), has_shown_bubble_view_(false), bubble_view_(NULL) {
-  AutomaticProfileResetter* automatic_profile_resetter =
-      AutomaticProfileResetterFactory::GetForBrowserContext(profile_);
-  if (automatic_profile_resetter)
-    automatic_profile_resetter_ = automatic_profile_resetter->AsWeakPtr();
-}
-
-ProfileResetGlobalError::~ProfileResetGlobalError() {
-  if (!has_shown_bubble_view_)
-    RecordPromptDelay(GetPromptDelayHistogramMaximum());
-}
-
-// static
-bool ProfileResetGlobalError::IsSupportedOnPlatform(Browser* browser) {
-  return browser->window()->IsProfileResetBubbleSupported();
-}
-
-bool ProfileResetGlobalError::HasMenuItem() { return true; }
-
-int ProfileResetGlobalError::MenuItemCommandID() {
-  return IDC_SHOW_SETTINGS_RESET_BUBBLE;
-}
-
-base::string16 ProfileResetGlobalError::MenuItemLabel() {
-  return l10n_util::GetStringFUTF16(
-      IDS_RESET_SETTINGS_MENU_ITEM,
-      l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_NAME));
-}
-
-void ProfileResetGlobalError::ExecuteMenuItem(Browser* browser) {
-  chrome::ShowSettingsSubPage(browser, chrome::kResetProfileSettingsSubPage);
-}
-
-bool ProfileResetGlobalError::HasBubbleView() { return true; }
-
-bool ProfileResetGlobalError::HasShownBubbleView() {
-  return has_shown_bubble_view_;
-}
-
-void ProfileResetGlobalError::ShowBubbleView(Browser* browser) {
-  if (has_shown_bubble_view_)
-    return;
-
-  has_shown_bubble_view_ = true;
-  bubble_view_ = browser->window()->ShowProfileResetBubble(AsWeakPtr());
-
-  if (automatic_profile_resetter_)
-    automatic_profile_resetter_->NotifyDidShowResetBubble();
-  RecordPromptDelay(timer_.Elapsed());
-}
-
-void ProfileResetGlobalError::OnBubbleViewDidClose() {
-  bubble_view_ = NULL;
-}
-
-void ProfileResetGlobalError::OnBubbleViewResetButtonPressed(
-    bool send_feedback) {
-  if (automatic_profile_resetter_)
-    automatic_profile_resetter_->TriggerProfileReset(send_feedback);
-}
-
-void ProfileResetGlobalError::OnBubbleViewNoThanksButtonPressed() {
-  if (automatic_profile_resetter_)
-    automatic_profile_resetter_->SkipProfileReset();
-}
-
-GlobalErrorBubbleViewBase* ProfileResetGlobalError::GetBubbleView() {
-  return bubble_view_;
-}
diff --git a/chrome/browser/profile_resetter/profile_reset_global_error.h b/chrome/browser/profile_resetter/profile_reset_global_error.h
deleted file mode 100644
index e3031fc..0000000
--- a/chrome/browser/profile_resetter/profile_reset_global_error.h
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_PROFILE_RESETTER_PROFILE_RESET_GLOBAL_ERROR_H_
-#define CHROME_BROWSER_PROFILE_RESETTER_PROFILE_RESET_GLOBAL_ERROR_H_
-
-#include "base/basictypes.h"
-#include "base/memory/weak_ptr.h"
-#include "base/timer/elapsed_timer.h"
-#include "chrome/browser/ui/global_error/global_error.h"
-
-class AutomaticProfileResetter;
-class GlobalErrorBubbleViewBase;
-class Profile;
-
-// Encapsulates UI-related functionality for the one-time profile settings reset
-// prompt. The UI consists of two parts: (1.) the profile reset (pop-up) bubble,
-// and (2.) a menu item in the wrench menu (provided by us being a GlobalError).
-class ProfileResetGlobalError
-    : public GlobalError,
-      public base::SupportsWeakPtr<ProfileResetGlobalError> {
- public:
-  explicit ProfileResetGlobalError(Profile* profile);
-  ~ProfileResetGlobalError() override;
-
-  // Returns whether or not the reset prompt is supported on this platform.
-  static bool IsSupportedOnPlatform(Browser* browser);
-
-  // Called by the bubble view when it is closed.
-  void OnBubbleViewDidClose();
-
-  // Called when the user clicks on the 'Reset' button. The user can choose to
-  // send feedback containing the old settings that are now being reset, this is
-  // indicated by |send_feedback|.
-  void OnBubbleViewResetButtonPressed(bool send_feedback);
-
-  // Called when the user clicks the 'No, thanks' button.
-  void OnBubbleViewNoThanksButtonPressed();
-
-  // GlobalError:
-  bool HasMenuItem() override;
-  int MenuItemCommandID() override;
-  base::string16 MenuItemLabel() override;
-  void ExecuteMenuItem(Browser* browser) override;
-  bool HasBubbleView() override;
-  bool HasShownBubbleView() override;
-  void ShowBubbleView(Browser* browser) override;
-  GlobalErrorBubbleViewBase* GetBubbleView() override;
-
- private:
-  Profile* profile_;
-
-  // GlobalErrorService owns us, on which AutomaticProfileResetter depends, so
-  // during shutdown, it may get destroyed before we are.
-  // Note: the AutomaticProfileResetter expects call-backs from us to always be
-  // synchronous, so that there will be no call-backs once we are destroyed.
-  base::WeakPtr<AutomaticProfileResetter> automatic_profile_resetter_;
-
-  // Used to measure the delay before the bubble actually gets shown.
-  base::ElapsedTimer timer_;
-
-  // Whether or not we have already shown the bubble.
-  bool has_shown_bubble_view_;
-
-  // The reset bubble, if we're currently showing one.
-  GlobalErrorBubbleViewBase* bubble_view_;
-
-  DISALLOW_COPY_AND_ASSIGN(ProfileResetGlobalError);
-};
-
-#endif  // CHROME_BROWSER_PROFILE_RESETTER_PROFILE_RESET_GLOBAL_ERROR_H_
diff --git a/chrome/browser/profile_resetter/resettable_settings_snapshot.cc b/chrome/browser/profile_resetter/resettable_settings_snapshot.cc
index 42c6f59..504876b 100644
--- a/chrome/browser/profile_resetter/resettable_settings_snapshot.cc
+++ b/chrome/browser/profile_resetter/resettable_settings_snapshot.cc
@@ -31,8 +31,7 @@
 
 namespace {
 
-// Feedback bucket labels.
-const char kProfileResetPromptBucket[] = "SamplingOfSettingsResetPrompt";
+// Feedback bucket label.
 const char kProfileResetWebUIBucket[] = "ProfileResetReport";
 
 // Dictionary keys for feedback report.
@@ -222,19 +221,9 @@
 }
 
 void SendSettingsFeedback(const std::string& report,
-                          Profile* profile,
-                          SnapshotCaller caller) {
+                          Profile* profile) {
   scoped_refptr<FeedbackData> feedback_data = new FeedbackData();
-  std::string bucket;
-  switch (caller) {
-    case PROFILE_RESET_WEBUI:
-      bucket = kProfileResetWebUIBucket;
-      break;
-    case PROFILE_RESET_PROMPT:
-      bucket = kProfileResetPromptBucket;
-      break;
-  }
-  feedback_data->set_category_tag(bucket);
+  feedback_data->set_category_tag(kProfileResetWebUIBucket);
   feedback_data->set_description(report);
 
   feedback_data->set_image(make_scoped_ptr(new std::string));
diff --git a/chrome/browser/profile_resetter/resettable_settings_snapshot.h b/chrome/browser/profile_resetter/resettable_settings_snapshot.h
index 2022e97..e602cef 100644
--- a/chrome/browser/profile_resetter/resettable_settings_snapshot.h
+++ b/chrome/browser/profile_resetter/resettable_settings_snapshot.h
@@ -115,12 +115,6 @@
   DISALLOW_COPY_AND_ASSIGN(ResettableSettingsSnapshot);
 };
 
-// The caller of ResettableSettingsSnapshot.
-enum SnapshotCaller {
-  PROFILE_RESET_WEBUI = 0,
-  PROFILE_RESET_PROMPT,
-};
-
 // Serializes specified |snapshot| members to JSON format. |field_mask| is a bit
 // mask of ResettableSettingsSnapshot::Field values.
 std::string SerializeSettingsReport(const ResettableSettingsSnapshot& snapshot,
@@ -129,8 +123,7 @@
 // Sends |report| as a feedback. |report| is supposed to be result of
 // SerializeSettingsReport().
 void SendSettingsFeedback(const std::string& report,
-                          Profile* profile,
-                          SnapshotCaller caller);
+                          Profile* profile);
 
 // Returns list of key/value pairs for all available reported information
 // from the |profile| and some additional fields.
diff --git a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
index d5f51d649..bb7784e 100644
--- a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
+++ b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
@@ -123,7 +123,6 @@
 #endif
 
 #if !defined(OS_ANDROID)
-#include "chrome/browser/profile_resetter/automatic_profile_resetter_factory.h"
 #include "chrome/browser/ui/global_error/global_error_service_factory.h"
 #include "chrome/browser/usb/usb_chooser_context_factory.h"
 #endif
@@ -184,9 +183,6 @@
   AccountTrackerServiceFactory::GetInstance();
   AccountFetcherServiceFactory::GetInstance();
   autofill::PersonalDataManagerFactory::GetInstance();
-#if !defined(OS_ANDROID)
-  AutomaticProfileResetterFactory::GetInstance();
-#endif
 #if defined(ENABLE_BACKGROUND)
   BackgroundContentsServiceFactory::GetInstance();
 #endif
diff --git a/chrome/browser/profiles/profile_io_data.cc b/chrome/browser/profiles/profile_io_data.cc
index 3e331d5..83fe26b7 100644
--- a/chrome/browser/profiles/profile_io_data.cc
+++ b/chrome/browser/profiles/profile_io_data.cc
@@ -128,7 +128,6 @@
 #include "chrome/browser/chromeos/net/cert_verify_proc_chromeos.h"
 #include "chrome/browser/chromeos/net/client_cert_filter_chromeos.h"
 #include "chrome/browser/chromeos/net/client_cert_store_chromeos.h"
-#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
 #include "chrome/browser/chromeos/policy/policy_cert_service.h"
 #include "chrome/browser/chromeos/policy/policy_cert_service_factory.h"
 #include "chrome/browser/chromeos/policy/policy_cert_verifier.h"
@@ -449,14 +448,9 @@
                                          user->username_hash(),
                                          profile->GetPath()));
 
-      // Use the device-wide system key slot only if the user is of the same
-      // domain as the device is registered to.
-      policy::BrowserPolicyConnectorChromeOS* connector =
-          g_browser_process->platform_part()
-              ->browser_policy_connector_chromeos();
-      params->use_system_key_slot =
-          connector->GetUserAffiliation(user->email()) ==
-          policy::USER_AFFILIATION_MANAGED;
+      // Use the device-wide system key slot only if the user is affiliated on
+      // the device.
+      params->use_system_key_slot = user->is_affiliated();
     }
   }
 
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu.cc b/chrome/browser/renderer_context_menu/render_view_context_menu.cc
index 1e571a2a..0e2dfe16 100644
--- a/chrome/browser/renderer_context_menu/render_view_context_menu.cc
+++ b/chrome/browser/renderer_context_menu/render_view_context_menu.cc
@@ -1547,12 +1547,6 @@
     case IDC_SPELLPANEL_TOGGLE:
     case IDC_CONTENT_CONTEXT_LANGUAGE_SETTINGS:
       return true;
-    case IDC_CONTENT_CONTEXT_VIEWFRAMEINFO:
-      // Disabled if no browser is associated (e.g. desktop notifications).
-      if (chrome::FindBrowserWithWebContents(source_web_contents_) == NULL)
-        return false;
-      return true;
-
     case IDC_CHECK_SPELLING_WHILE_TYPING:
       return prefs->GetBoolean(prefs::kEnableContinuousSpellcheck);
 
@@ -2004,20 +1998,6 @@
                                             params_.frame_page_state);
       break;
 
-    case IDC_CONTENT_CONTEXT_VIEWFRAMEINFO: {
-      Browser* browser = chrome::FindBrowserWithWebContents(
-          source_web_contents_);
-      SecurityStateModel::SecurityInfo security_info;
-      SecurityStateModel::SecurityInfoForRequest(
-          params_.frame_url, params_.security_info,
-          Profile::FromBrowserContext(
-              source_web_contents_->GetBrowserContext()),
-          &security_info);
-      chrome::ShowWebsiteSettings(browser, source_web_contents_,
-                                  params_.frame_url, security_info);
-      break;
-    }
-
     case IDC_CONTENT_CONTEXT_UNDO:
       source_web_contents_->Undo();
       break;
diff --git a/chrome/browser/resources/chromeos/chromevox/common/msgs.js b/chrome/browser/resources/chromeos/chromevox/common/msgs.js
index 8a9628e..1492db7 100644
--- a/chrome/browser/resources/chromeos/chromevox/common/msgs.js
+++ b/chrome/browser/resources/chromeos/chromevox/common/msgs.js
@@ -50,7 +50,7 @@
 Msgs.getMsg = function(messageId, opt_subs) {
   var message = Msgs.Untranslated[messageId.toUpperCase()];
   if (message !== undefined)
-    return message;
+    return Msgs.applySubstitutions_(message, opt_subs);
   message = chrome.i18n.getMessage(
       Msgs.NAMESPACE_ + messageId, opt_subs);
   if (message == undefined || message == '') {
@@ -111,6 +111,23 @@
 };
 
 /**
+ * Applies substitions of the form $N, where N is a number from 1 to 9, to a
+ * string. The numbers are one-based indices into |opt_subs|.
+ * @param {string} message
+ * @param {Array<string>=} opt_subs
+ * @return {string}
+ * @private
+ */
+Msgs.applySubstitutions_ = function(message, opt_subs) {
+  if (opt_subs) {
+    for (var i = 0; i < opt_subs.length; i++) {
+      message = message.replace('$' + (i + 1), opt_subs[i]);
+    }
+  }
+  return message;
+};
+
+/**
  * Strings that are displayed in the user interface but don't need
  * be translated.
  * @type {Object<string>}
@@ -156,6 +173,14 @@
   ARIA_SELECTED_FALSE_BRL: '( )',
   /** Brailled after a menu if it has a submenu. */
   HAS_SUBMENU_BRL: '->',
-  /** Brailled to describe a &lt;time&gt; tag. */
+  /** Brailled to describe a <time> tag. */
   TAG_TIME_BRL: ' ',
+  /** Spoken when describing an ARIA value. */
+  ARIA_VALUE_NOW: '$1',
+  /** Brailled when describing an ARIA value. */
+  ARIA_VALUE_NOW_BRL: '$1',
+  /** Spoken when describing an ARIA value text. */
+  ARIA_VALUE_TEXT: '$1',
+  /** Brailled when describing an ARIA value text. */
+  ARIA_VALUE_TEXT_BRL: '$1',
 };
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings.grd b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings.grd
index d1b911c7..878212f 100644
--- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings.grd
+++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings.grd
@@ -944,18 +944,6 @@
       <message desc='Brailled when describing an ARIA value maximum. For example "Distance, in meters: 6 min:2 max:10".' name="IDS_CHROMEVOX_ARIA_VALUE_MAX_BRL">
         max:<ph name="x">$1</ph>
       </message>
-      <message desc='Spoken when describing an ARIA value. For example "Distance, in meters textbox 6, min 2, max 10".' name="IDS_CHROMEVOX_ARIA_VALUE_NOW">
-        <ph name="x">$1</ph>
-      </message>
-      <message desc='Brailled when describing an ARIA value. For example "Distance, in meters: 6 min:2 max:10".' name="IDS_CHROMEVOX_ARIA_VALUE_NOW_BRL">
-        <ph name="x">$1</ph>
-      </message>
-      <message desc='Spoken when describing an ARIA value text. For example "Distance, short distance set"' name="IDS_CHROMEVOX_ARIA_VALUE_TEXT">
-        <ph name="x">$1</ph>
-      </message>
-      <message desc='Brailled when describing an ARIA value text. For example "Distance, short distance set"' name="IDS_CHROMEVOX_ARIA_VALUE_TEXT_BRL">
-        <ph name="x">$1</ph>
-      </message>
       <message desc="Describes an element with the ARIA role alert." name="IDS_CHROMEVOX_ROLE_ALERT">
         Alert
       </message>
diff --git a/chrome/browser/resources/chromeos/chromevox/testing/test_msgs.js b/chrome/browser/resources/chromeos/chromevox/testing/test_msgs.js
index 969dd04..beec2a6 100644
--- a/chrome/browser/resources/chromeos/chromevox/testing/test_msgs.js
+++ b/chrome/browser/resources/chromeos/chromevox/testing/test_msgs.js
@@ -18,6 +18,12 @@
 TestMsgs = function() {};
 
 /**
+ * @type {function(string, Array<string>=): string}
+ * @private
+ */
+TestMsgs.applySubstitutions_ = Msgs.applySubstitutions_;
+
+/**
  * @type {Object<string>}
  */
 TestMsgs.Untranslated = Msgs.Untranslated;
@@ -38,30 +44,23 @@
   if (!messageId) {
     throw Error('Message id required');
   }
-  var message = TestMsgs.Untranslated[messageId.toUpperCase()];
-  if (message !== undefined)
-    return message;
-  message = cvox.TestMessages[('chromevox_' + messageId).toUpperCase()];
-  if (message === undefined) {
-    throw Error('missing-msg: ' + messageId);
-  }
-
-  var messageString = message.message;
-  var placeholders = message.placeholders;
-  if (placeholders) {
-    for (name in placeholders) {
-      messageString = messageString.replace(
-          '$' + name + '$',
-          placeholders[name].content);
+  var messageString = TestMsgs.Untranslated[messageId.toUpperCase()];
+  if (messageString === undefined) {
+    var messageObj = cvox.TestMessages[(
+        'chromevox_' + messageId).toUpperCase()];
+    if (messageObj === undefined)
+      throw Error('missing-msg: ' + messageId);
+    var messageString = messageObj.message;
+    var placeholders = messageObj.placeholders;
+    if (placeholders) {
+      for (name in placeholders) {
+        messageString = messageString.replace(
+            '$' + name + '$',
+            placeholders[name].content);
+      }
     }
   }
-  if (opt_subs) {
-    // Unshift a null to make opt_subs and message.placeholders line up.
-    for (var i = 0; i < opt_subs.length; i++) {
-      messageString = messageString.replace('$' + (i + 1), opt_subs[i]);
-    }
-  }
-  return messageString;
+  return Msgs.applySubstitutions_(messageString, opt_subs);
 };
 
 /**
diff --git a/chrome/browser/resources/options/settings_banner.css b/chrome/browser/resources/options/automatic_settings_reset_banner.css
similarity index 89%
rename from chrome/browser/resources/options/settings_banner.css
rename to chrome/browser/resources/options/automatic_settings_reset_banner.css
index c4290ef..a62408f3 100644
--- a/chrome/browser/resources/options/settings_banner.css
+++ b/chrome/browser/resources/options/automatic_settings_reset_banner.css
@@ -2,9 +2,6 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file. */
 
-/* These styles are used by both reset_profile_settings_banner.html and
- * automatic_settings_reset_banner.html. */
-
 .settings-banner {
   background-color: #f5f5f5;
   border-color: #c8c8c8;
@@ -43,8 +40,8 @@
 }
 
 .settings-banner .content-area {
-  -webkit-box-align: center;
-  display: -webkit-box;
+  align-items: center;
+  display: flex;
   padding: 17px;
 }
 
@@ -57,8 +54,8 @@
 }
 
 .settings-banner .content-area .text {
-  -webkit-box-flex: 1.0;
   -webkit-margin-start: 18px;
+  flex: 1.0;
 }
 
 .settings-banner .content-area .text p {
diff --git a/chrome/browser/resources/options/automatic_settings_reset_banner.js b/chrome/browser/resources/options/automatic_settings_reset_banner.js
index e0747c58..bdd9090 100644
--- a/chrome/browser/resources/options/automatic_settings_reset_banner.js
+++ b/chrome/browser/resources/options/automatic_settings_reset_banner.js
@@ -5,7 +5,6 @@
 // Note: the native-side handler for this is AutomaticSettingsResetHandler.
 
 cr.define('options', function() {
-  /** @const */ var SettingsBannerBase = options.SettingsBannerBase;
   /** @const */ var PageManager = cr.ui.pageManager.PageManager;
 
   /**
@@ -19,7 +18,38 @@
   cr.addSingletonGetter(AutomaticSettingsResetBanner);
 
   AutomaticSettingsResetBanner.prototype = {
-    __proto__: SettingsBannerBase.prototype,
+    /**
+     * Whether or not the banner has already been dismissed.
+     *
+     * This is needed because of the surprising ordering of asynchronous
+     * JS<->native calls when the settings page is opened with specifying a
+     * given sub-page, e.g. chrome://settings/AutomaticSettingsReset.
+     *
+     * In such a case, AutomaticSettingsResetOverlay's didShowPage(), which
+     * calls our dismiss() method, would be called before the native Handlers'
+     * InitalizePage() methods have an effect in the JS, which includes calling
+     * our show() method. This would mean that the banner would be first
+     * dismissed, then shown. We want to prevent this.
+     *
+     * @type {boolean}
+     * @private
+     */
+    hadBeenDismissed_: false,
+
+    /**
+     * Metric name to send when a show event occurs.
+     */
+    showMetricName_: '',
+
+    /**
+     * Name of the native callback invoked when the banner is dismised.
+     */
+    dismissNativeCallbackName_: '',
+
+    /**
+     * DOM element whose visibility is set when setVisibility_ is called.
+     */
+    setVisibilibyDomElement_: null,
 
     /**
      * Initializes the banner's event handlers.
@@ -31,12 +61,12 @@
      * private implementations using cr.makePublic().
      */
     initialize: function() {
-      this.showMetricName = 'AutomaticSettingsReset_WebUIBanner_BannerShown';
+      this.showMetricName_ = 'AutomaticSettingsReset_WebUIBanner_BannerShown';
 
-      this.dismissNativeCallbackName =
+      this.dismissNativeCallbackName_ =
           'onDismissedAutomaticSettingsResetBanner';
 
-      this.visibilityDomElement = $('automatic-settings-reset-banner');
+      this.setVisibilibyDomElement_ = $('automatic-settings-reset-banner');
 
       $('automatic-settings-reset-banner-close').onclick = function(event) {
         chrome.send('metricsHandler:recordAction',
@@ -54,18 +84,45 @@
         PageManager.showPageByName('resetProfileSettings');
       };
     },
+
+    /**
+     * Sets whether or not the reset profile settings banner shall be visible.
+     * @param {boolean} show Whether or not to show the banner.
+     * @protected
+     */
+    setVisibility: function(show) {
+      this.setVisibilibyDomElement_.hidden = !show;
+    },
+
+    /**
+     * Called by the native code to show the banner if needed.
+     * @private
+     */
+    show_: function() {
+      if (!this.hadBeenDismissed_) {
+        chrome.send('metricsHandler:recordAction', [this.showMetricName_]);
+        this.setVisibility(true);
+      }
+    },
+
+    /**
+     * Called when the banner should be closed as a result of something taking
+     * place on the WebUI page, i.e. when its close button is pressed, or when
+     * the confirmation dialog for the profile settings reset feature is opened.
+     * @private
+     */
+    dismiss_: function() {
+      chrome.send(this.dismissNativeCallbackName_);
+      this.hadBeenDismissed_ = true;
+      this.setVisibility(false);
+    },
   };
 
-  // Forward public APIs to protected implementations.
-  [
+  // Forward public APIs to private implementations.
+  cr.makePublic(AutomaticSettingsResetBanner, [
     'show',
     'dismiss',
-  ].forEach(function(name) {
-    AutomaticSettingsResetBanner[name] = function() {
-      var instance = AutomaticSettingsResetBanner.getInstance();
-      return instance[name].apply(instance, arguments);
-    };
-  });
+  ]);
 
   // Export
   return {
diff --git a/chrome/browser/resources/options/browser_options.html b/chrome/browser/resources/options/browser_options.html
index 3dd0fdd..9733e77 100644
--- a/chrome/browser/resources/options/browser_options.html
+++ b/chrome/browser/resources/options/browser_options.html
@@ -2,7 +2,6 @@
   <header>
     <h1 i18n-content="settingsTitle"></h1>
   </header>
-  <include src="reset_profile_settings_banner.html">
   <include src="automatic_settings_reset_banner.html">
 <if expr="chromeos">
   <link rel="import" href="chrome://resources/cr_elements/network/cr_network_icon.html">
diff --git a/chrome/browser/resources/options/options.html b/chrome/browser/resources/options/options.html
index 14196b3..e6e1ee2b 100644
--- a/chrome/browser/resources/options/options.html
+++ b/chrome/browser/resources/options/options.html
@@ -17,6 +17,7 @@
 <link rel="stylesheet" href="alert_overlay.css">
 <link rel="stylesheet" href="autofill_edit_overlay.css">
 <link rel="stylesheet" href="autofill_options.css">
+<link rel="stylesheet" href="automatic_settings_reset_banner.css">
 <link rel="stylesheet" href="browser_options.css">
 <if expr="chromeos">
   <link rel="stylesheet" href="chromeos/browser_options.css">
@@ -41,7 +42,6 @@
 <link rel="stylesheet" href="reset_profile_settings_overlay.css">
 <link rel="stylesheet" href="search_engine_manager.css">
 <link rel="stylesheet" href="search_page.css">
-<link rel="stylesheet" href="settings_banner.css">
 <link rel="stylesheet" href="spelling_confirm_overlay.css">
 <link rel="stylesheet" href="startup_overlay.css">
 <link rel="stylesheet" href="subpages_tab_controls.css">
diff --git a/chrome/browser/resources/options/options.js b/chrome/browser/resources/options/options.js
index ab78887..d331855 100644
--- a/chrome/browser/resources/options/options.js
+++ b/chrome/browser/resources/options/options.js
@@ -35,7 +35,6 @@
 var PasswordManager = options.PasswordManager;
 var Preferences = options.Preferences;
 var PreferredNetworks = options.PreferredNetworks;
-var ResetProfileSettingsBanner = options.ResetProfileSettingsBanner;
 var ResetProfileSettingsOverlay = options.ResetProfileSettingsOverlay;
 var SearchEngineManager = options.SearchEngineManager;
 var SearchPage = options.SearchPage;
@@ -240,7 +239,6 @@
 
   OptionsFocusManager.getInstance().initialize();
   Preferences.getInstance().initialize();
-  ResetProfileSettingsBanner.getInstance().initialize();
   AutomaticSettingsResetBanner.getInstance().initialize();
   OptionsPage.initialize();
   PageManager.initialize(BrowserOptions.getInstance());
diff --git a/chrome/browser/resources/options/options_bundle.js b/chrome/browser/resources/options/options_bundle.js
index 27502bf..8a72e0d 100644
--- a/chrome/browser/resources/options/options_bundle.js
+++ b/chrome/browser/resources/options/options_bundle.js
@@ -14,7 +14,6 @@
 <include src="options_page.js">
 <include src="pref_ui.js">
 <include src="settings_dialog.js">
-<include src="settings_banner.js">
 <if expr="chromeos">
 <include src="../chromeos/user_images_grid.js">
 <include src="../help/channel_change_page.js">
@@ -104,7 +103,6 @@
 <include src="password_manager.js">
 <include src="password_manager_list.js">
 <include src="profiles_icon_grid.js">
-<include src="reset_profile_settings_banner.js">
 <include src="reset_profile_settings_overlay.js">
 <include src="search_engine_manager.js">
 <include src="search_engine_manager_engine_list.js">
diff --git a/chrome/browser/resources/options/reset_profile_settings_banner.html b/chrome/browser/resources/options/reset_profile_settings_banner.html
deleted file mode 100644
index fd95c3c..0000000
--- a/chrome/browser/resources/options/reset_profile_settings_banner.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<div id="reset-profile-settings-banner" class="settings-banner" hidden>
-  <div id="reset-profile-settings-banner-close" class="close-button"></div>
-  <div class="content-area">
-    <div class="badge"></div>
-    <div class="text">
-      <p>
-        <span i18n-values=".innerHTML:resetProfileSettingsBannerText">
-        </span>
-        <a class="nowrap" i18n-values="href:resetProfileSettingsLearnMoreUrl"
-            i18n-content="learnMore" target="_blank"></a>
-      </p>
-    </div>
-    <div class="button-area">
-      <button id="reset-profile-settings-banner-activate"
-          i18n-content="resetProfileSettings"></button>
-    </div>
-  </div>
-</div>
diff --git a/chrome/browser/resources/options/reset_profile_settings_banner.js b/chrome/browser/resources/options/reset_profile_settings_banner.js
deleted file mode 100644
index 4785113..0000000
--- a/chrome/browser/resources/options/reset_profile_settings_banner.js
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Note: the native-side handler for this is ResetProfileSettingsHandler.
-
-cr.define('options', function() {
-  /** @const */ var PageManager = cr.ui.pageManager.PageManager;
-  /** @const */ var SettingsBannerBase = options.SettingsBannerBase;
-
-  /**
-   * ResetProfileSettingsBanner class
-   * Provides encapsulated handling of the Reset Profile Settings banner.
-   * @constructor
-   * @extends {options.SettingsBannerBase}
-   */
-  function ResetProfileSettingsBanner() {}
-
-  cr.addSingletonGetter(ResetProfileSettingsBanner);
-
-  ResetProfileSettingsBanner.prototype = {
-    __proto__: SettingsBannerBase.prototype,
-
-    /**
-     * Initializes the banner's event handlers.
-     * @suppress {checkTypes}
-     * TODO(vitalyp): remove the suppression. See the explanation in
-     * chrome/browser/resources/options/automatic_settings_reset_banner.js.
-     */
-    initialize: function() {
-      this.showMetricName = 'AutomaticReset_WebUIBanner_BannerShown';
-
-      this.dismissNativeCallbackName =
-          'onDismissedResetProfileSettingsBanner';
-
-      this.visibilityDomElement = $('reset-profile-settings-banner');
-
-      $('reset-profile-settings-banner-close').onclick = function(event) {
-        chrome.send('metricsHandler:recordAction',
-            ['AutomaticReset_WebUIBanner_ManuallyClosed']);
-        ResetProfileSettingsBanner.dismiss();
-      };
-      $('reset-profile-settings-banner-activate').onclick = function(event) {
-        chrome.send('metricsHandler:recordAction',
-            ['AutomaticReset_WebUIBanner_ResetClicked']);
-        PageManager.showPageByName('resetProfileSettings');
-      };
-    },
-  };
-
-  // Forward public APIs to protected implementations.
-  [
-    'show',
-    'dismiss',
-  ].forEach(function(name) {
-    ResetProfileSettingsBanner[name] = function() {
-      var instance = ResetProfileSettingsBanner.getInstance();
-      return instance[name].apply(instance, arguments);
-    };
-  });
-
-  // Export
-  return {
-    ResetProfileSettingsBanner: ResetProfileSettingsBanner
-  };
-});
diff --git a/chrome/browser/resources/options/reset_profile_settings_overlay.js b/chrome/browser/resources/options/reset_profile_settings_overlay.js
index 2c247dc..7da9e29 100644
--- a/chrome/browser/resources/options/reset_profile_settings_overlay.js
+++ b/chrome/browser/resources/options/reset_profile_settings_overlay.js
@@ -6,7 +6,6 @@
   var Page = cr.ui.pageManager.Page;
 
   var AutomaticSettingsResetBanner = options.AutomaticSettingsResetBanner;
-  var ResetProfileSettingsBanner = options.ResetProfileSettingsBanner;
 
   /**
    * ResetProfileSettingsOverlay class
@@ -57,7 +56,6 @@
       $('reset-profile-settings-explanation').textContent =
           loadTimeData.getString('resetProfileSettingsExplanation');
 
-      ResetProfileSettingsBanner.dismiss();
       chrome.send('onShowResetProfileDialog');
     },
 
diff --git a/chrome/browser/resources/options/settings_banner.js b/chrome/browser/resources/options/settings_banner.js
deleted file mode 100644
index 666aaf2..0000000
--- a/chrome/browser/resources/options/settings_banner.js
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-cr.define('options', function() {
-
-  /**
-   * Base class for banners that appear at the top of the settings page.
-   * @constructor
-   */
-  function SettingsBannerBase() {}
-
-  cr.addSingletonGetter(SettingsBannerBase);
-
-  SettingsBannerBase.prototype = {
-    /**
-     * Whether or not the banner has already been dismissed.
-     *
-     * This is needed because of the surprising ordering of asynchronous
-     * JS<->native calls when the settings page is opened with specifying a
-     * given sub-page, e.g. chrome://settings/AutomaticSettingsReset.
-     *
-     * In such a case, AutomaticSettingsResetOverlay's didShowPage(), which
-     * calls our dismiss() method, would be called before the native Handlers'
-     * InitalizePage() methods have an effect in the JS, which includes calling
-     * our show() method. This would mean that the banner would be first
-     * dismissed, then shown. We want to prevent this.
-     *
-     * @type {boolean}
-     * @private
-     */
-    hadBeenDismissed_: false,
-
-    /**
-     * Metric name to send when a show event occurs.
-     * @protected
-     */
-    showMetricName: '',
-
-    /**
-     * Name of the native callback invoked when the banner is dismised.
-     * @protected
-     */
-    dismissNativeCallbackName: '',
-
-    /**
-     * DOM element whose visibility is set when setVisibility_ is called.
-     * @protected
-     */
-    visibilityDomElement: null,
-
-    /**
-     * Called by the native code to show the banner if needed.
-     * @protected
-     */
-    show: function() {
-      if (!this.hadBeenDismissed_) {
-        chrome.send('metricsHandler:recordAction', [this.showMetricName]);
-        this.setVisibility_(true);
-      }
-    },
-
-    /**
-     * Called when the banner should be closed as a result of something taking
-     * place on the WebUI page, i.e. when its close button is pressed, or when
-     * the confirmation dialog for the profile settings reset feature is opened.
-     * @protected
-     */
-    dismiss: function() {
-      chrome.send(this.dismissNativeCallbackName);
-      this.hadBeenDismissed_ = true;
-      this.setVisibility_(false);
-    },
-
-    /**
-     * Sets whether or not the reset profile settings banner shall be visible.
-     * @param {boolean} show Whether or not to show the banner.
-     * @private
-     */
-    setVisibility_: function(show) {
-      this.visibilityDomElement.hidden = !show;
-    },
-  };
-
-  // Export
-  return {
-    SettingsBannerBase: SettingsBannerBase
-  };
-});
diff --git a/chrome/browser/resources/options/triggered_reset_profile_settings_overlay.js b/chrome/browser/resources/options/triggered_reset_profile_settings_overlay.js
index 9ed58cb..35cd029 100644
--- a/chrome/browser/resources/options/triggered_reset_profile_settings_overlay.js
+++ b/chrome/browser/resources/options/triggered_reset_profile_settings_overlay.js
@@ -6,7 +6,6 @@
   var Page = cr.ui.pageManager.Page;
 
   var ResetProfileSettingsOverlay = options.ResetProfileSettingsOverlay;
-  var ResetProfileSettingsBanner = options.ResetProfileSettingsBanner;
 
   /**
    * TriggeredResetProfileSettingsOverlay class
@@ -37,7 +36,6 @@
           loadTimeData.getString('triggeredResetProfileSettingsOverlay');
       $('reset-profile-settings-explanation').textContent =
           loadTimeData.getString('triggeredResetProfileSettingsExplanation');
-      ResetProfileSettingsBanner.dismiss();
       chrome.send('onShowResetProfileDialog');
     },
   };
diff --git a/chrome/browser/safe_browsing/download_feedback_service.cc b/chrome/browser/safe_browsing/download_feedback_service.cc
index 379f0ad..e5cabd5d 100644
--- a/chrome/browser/safe_browsing/download_feedback_service.cc
+++ b/chrome/browser/safe_browsing/download_feedback_service.cc
@@ -178,13 +178,13 @@
     const std::string& ping_response,
     const base::FilePath& path) {
   DCHECK(CalledOnValidThread());
-  DownloadFeedback* feedback =
+  scoped_ptr<DownloadFeedback> feedback(
       DownloadFeedback::Create(request_context_getter_.get(),
                                file_task_runner_.get(),
                                path,
                                ping_request,
-                               ping_response);
-  active_feedback_.push_back(feedback);
+                               ping_response));
+  active_feedback_.push_back(feedback.Pass());
   UMA_HISTOGRAM_COUNTS_100("SBDownloadFeedback.ActiveFeedbacks",
                            active_feedback_.size());
 
diff --git a/chrome/browser/safe_browsing/download_feedback_service.h b/chrome/browser/safe_browsing/download_feedback_service.h
index 65a7f1f..d1ef35c 100644
--- a/chrome/browser/safe_browsing/download_feedback_service.h
+++ b/chrome/browser/safe_browsing/download_feedback_service.h
@@ -6,10 +6,11 @@
 #define CHROME_BROWSER_SAFE_BROWSING_DOWNLOAD_FEEDBACK_SERVICE_H_
 
 #include <string>
+#include <vector>
 
 #include "base/basictypes.h"
 #include "base/memory/ref_counted.h"
-#include "base/memory/scoped_vector.h"
+#include "base/memory/scoped_ptr.h"
 #include "base/threading/non_thread_safe.h"
 #include "chrome/browser/safe_browsing/download_protection_service.h"
 #include "content/public/browser/download_danger_type.h"
@@ -85,7 +86,7 @@
 
   // Currently active & pending uploads. The first item is active, remaining
   // items are pending.
-  ScopedVector<DownloadFeedback> active_feedback_;
+  std::vector<scoped_ptr<DownloadFeedback>> active_feedback_;
 
   base::WeakPtrFactory<DownloadFeedbackService> weak_ptr_factory_;
 
diff --git a/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.cc b/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.cc
index 14bddec..5f9ebab9 100644
--- a/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.cc
+++ b/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.cc
@@ -124,10 +124,10 @@
 
   // The incidents collected for this profile pending creation and/or upload.
   // Will contain null values for pruned incidents.
-  ScopedVector<Incident> incidents;
+  std::vector<scoped_ptr<Incident>> incidents;
 
   // The incidents data of which should be cleared.
-  ScopedVector<Incident> incidents_to_clear;
+  std::vector<scoped_ptr<Incident>> incidents_to_clear;
 
   // State storage for this profile; null until PROFILE_ADDED notification is
   // received.
@@ -265,7 +265,7 @@
 }
 
 IncidentReportingService::ProfileContext::~ProfileContext() {
-  for (Incident* incident : incidents) {
+  for (const auto& incident : incidents) {
     if (incident)
       LogIncidentDataType(DISCARDED, *incident);
   }
@@ -459,7 +459,7 @@
   // Drop all incidents associated with this profile that were received prior to
   // its addition if incident reporting is not enabled for it.
   if (!context->incidents.empty() && !enabled_for_profile) {
-    for (Incident* incident : context->incidents)
+    for (const auto& incident : context->incidents)
       LogIncidentDataType(DROPPED, *incident);
     context->incidents.clear();
   }
@@ -547,7 +547,7 @@
   // TODO(grt): Persist incidents for upload on future profile load.
 
   // Remove the association with this profile context from all pending uploads.
-  for (UploadContext* upload : uploads_)
+  for (const auto& upload : uploads_)
     upload->profiles_to_state.erase(context.get());
 
   // Forget about this profile. Incidents not yet sent for upload are lost.
@@ -606,7 +606,7 @@
   }
 
   // Take ownership of the incident.
-  context->incidents.push_back(incident.release());
+  context->incidents.push_back(incident.Pass());
 
   // Remember when the first incident for this report arrived.
   if (first_incident_time_.is_null())
@@ -628,7 +628,7 @@
 void IncidentReportingService::ClearIncident(Profile* profile,
                                              scoped_ptr<Incident> incident) {
   ProfileContext* context = GetOrCreateProfileContext(profile);
-  context->incidents_to_clear.push_back(incident.release());
+  context->incidents_to_clear.push_back(incident.Pass());
   // Begin processing to handle cleared incidents following collation.
   BeginReportProcessing();
 }
@@ -858,17 +858,15 @@
     if (eligible_profile) {
       ProfileContext* eligible_context = GetProfileContext(eligible_profile);
       // Move the incidents to the target context.
-      eligible_context->incidents.insert(eligible_context->incidents.end(),
-                                         null_context->incidents.begin(),
-                                         null_context->incidents.end());
-      null_context->incidents.weak_clear();
-      eligible_context->incidents_to_clear.insert(
-          eligible_context->incidents_to_clear.end(),
-          null_context->incidents_to_clear.begin(),
-          null_context->incidents_to_clear.end());
-      null_context->incidents_to_clear.weak_clear();
+      for (auto& incident : null_context->incidents) {
+        eligible_context->incidents.push_back(incident.Pass());
+      }
+      null_context->incidents.clear();
+      for (auto& incident : null_context->incidents_to_clear)
+        eligible_context->incidents_to_clear.push_back(incident.Pass());
+      null_context->incidents_to_clear.clear();
     } else {
-      for (Incident* incident : null_context->incidents)
+      for (const auto& incident : null_context->incidents)
         LogIncidentDataType(DROPPED, *incident);
       null_context->incidents.clear();
     }
@@ -884,7 +882,7 @@
     }
     ProfileContext* context = profile_and_context.second;
     StateStore::Transaction transaction(context->state_store.get());
-    for (Incident* incident : context->incidents_to_clear)
+    for (const auto& incident : context->incidents_to_clear)
       transaction.Clear(incident->GetType(), incident->GetKey());
     context->incidents_to_clear.clear();
   }
@@ -909,7 +907,7 @@
     if (context->incidents.empty())
       continue;
     if (!IsEnabledForProfile(profile_and_context.first)) {
-      for (Incident* incident : context->incidents)
+      for (const auto& incident : context->incidents)
         LogIncidentDataType(DROPPED, *incident);
       context->incidents.clear();
       continue;
@@ -917,7 +915,7 @@
     StateStore::Transaction transaction(context->state_store.get());
     std::vector<PersistentIncidentState> states;
     // Prep persistent data and prune any incidents already sent.
-    for (Incident* incident : context->incidents) {
+    for (const auto& incident : context->incidents) {
       const PersistentIncidentState state = ComputeIncidentState(*incident);
       if (context->state_store->HasBeenReported(state.type, state.key,
                                                 state.digest)) {
@@ -965,7 +963,7 @@
     // No database manager during testing. Take ownership of the context and
     // continue processing.
     UploadContext* temp_context = context.get();
-    uploads_.push_back(context.release());
+    uploads_.push_back(context.Pass());
     IncidentReportingService::OnKillSwitchResult(temp_context, false);
   } else {
     if (content::BrowserThread::PostTaskAndReplyWithResult(
@@ -976,7 +974,7 @@
             base::Bind(&IncidentReportingService::OnKillSwitchResult,
                        weak_ptr_factory_.GetWeakPtr(),
                        context.get()))) {
-      uploads_.push_back(context.release());
+      uploads_.push_back(context.Pass());
     }  // else should not happen. Let the context be deleted automatically.
   }
 }
@@ -1035,12 +1033,13 @@
 
   // The upload is no longer outstanding, so take ownership of the context (from
   // the collection of outstanding uploads) in this scope.
-  ScopedVector<UploadContext>::iterator it(
-      std::find(uploads_.begin(), uploads_.end(), context));
+  auto it = std::find_if(uploads_.begin(), uploads_.end(),
+                         [context] (const scoped_ptr<UploadContext>& value) {
+                           return value.get() == context;
+                         });
   DCHECK(it != uploads_.end());
-  scoped_ptr<UploadContext> upload(context);  // == *it
-  *it = uploads_.back();
-  uploads_.weak_erase(uploads_.end() - 1);
+  scoped_ptr<UploadContext> upload(it->Pass());
+  uploads_.erase(it);
 
   if (result == IncidentReportUploader::UPLOAD_SUCCESS)
     HandleResponse(*upload);
diff --git a/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.h b/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.h
index f92c8d8..14ac749 100644
--- a/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.h
+++ b/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.h
@@ -8,12 +8,12 @@
 #include <stdint.h>
 
 #include <map>
+#include <vector>
 
 #include "base/compiler_specific.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
-#include "base/memory/scoped_vector.h"
 #include "base/memory/weak_ptr.h"
 #include "base/threading/thread_checker.h"
 #include "base/time/time.h"
@@ -336,7 +336,7 @@
   DownloadMetadataManager download_metadata_manager_;
 
   // The collection of uploads in progress.
-  ScopedVector<UploadContext> uploads_;
+  std::vector<scoped_ptr<UploadContext>> uploads_;
 
   // An object that asynchronously searches for the most recent binary download.
   // Non-NULL while such a search is outstanding.
diff --git a/chrome/browser/safe_browsing/incident_reporting/mock_incident_receiver.h b/chrome/browser/safe_browsing/incident_reporting/mock_incident_receiver.h
index fb54790..36bebe7 100644
--- a/chrome/browser/safe_browsing/incident_reporting/mock_incident_receiver.h
+++ b/chrome/browser/safe_browsing/incident_reporting/mock_incident_receiver.h
@@ -42,7 +42,7 @@
 // An action that passes ownership of the incident in |arg0| to the vector in
 // |incidents|.
 ACTION_P(TakeIncidentToVector, incidents) {
-  incidents->push_back(arg0->release());
+  incidents->push_back(arg0->Pass());
 }
 
 }  // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/incident_reporting/preference_validation_delegate_unittest.cc b/chrome/browser/safe_browsing/incident_reporting/preference_validation_delegate_unittest.cc
index 0cf05dd..cd2ec7d2 100644
--- a/chrome/browser/safe_browsing/incident_reporting/preference_validation_delegate_unittest.cc
+++ b/chrome/browser/safe_browsing/incident_reporting/preference_validation_delegate_unittest.cc
@@ -9,7 +9,7 @@
 
 #include "base/bind.h"
 #include "base/compiler_specific.h"
-#include "base/memory/scoped_vector.h"
+#include "base/memory/scoped_ptr.h"
 #include "base/values.h"
 #include "chrome/browser/safe_browsing/incident_reporting/incident.h"
 #include "chrome/browser/safe_browsing/incident_reporting/mock_incident_receiver.h"
@@ -27,7 +27,7 @@
 // instance was provided with the expected data.
 class PreferenceValidationDelegateTest : public testing::Test {
  protected:
-  typedef ScopedVector<safe_browsing::Incident> IncidentVector;
+  typedef std::vector<scoped_ptr<safe_browsing::Incident>> IncidentVector;
 
   PreferenceValidationDelegateTest()
       : kPrefPath_("atomic.pref"),
diff --git a/chrome/browser/safe_browsing/local_database_manager.cc b/chrome/browser/safe_browsing/local_database_manager.cc
index e44cc8b..0abdac70 100644
--- a/chrome/browser/safe_browsing/local_database_manager.cc
+++ b/chrome/browser/safe_browsing/local_database_manager.cc
@@ -591,7 +591,7 @@
 
 void LocalSafeBrowsingDatabaseManager::AddChunks(
     const std::string& list,
-    scoped_ptr<ScopedVector<SBChunkData> > chunks,
+    scoped_ptr<std::vector<scoped_ptr<SBChunkData>>> chunks,
     AddChunksCallback callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   DCHECK(enabled_);
@@ -973,11 +973,11 @@
 
 void LocalSafeBrowsingDatabaseManager::AddDatabaseChunks(
     const std::string& list_name,
-    scoped_ptr<ScopedVector<SBChunkData> > chunks,
+    scoped_ptr<std::vector<scoped_ptr<SBChunkData>>> chunks,
     AddChunksCallback callback) {
   DCHECK(safe_browsing_task_runner_->RunsTasksOnCurrentThread());
   if (chunks)
-    GetDatabase()->InsertChunks(list_name, chunks->get());
+    GetDatabase()->InsertChunks(list_name, *chunks);
   BrowserThread::PostTask(
       BrowserThread::IO, FROM_HERE,
       base::Bind(&LocalSafeBrowsingDatabaseManager::OnAddChunksComplete, this,
diff --git a/chrome/browser/safe_browsing/local_database_manager.h b/chrome/browser/safe_browsing/local_database_manager.h
index d5cbe2e..3028346 100644
--- a/chrome/browser/safe_browsing/local_database_manager.h
+++ b/chrome/browser/safe_browsing/local_database_manager.h
@@ -237,9 +237,10 @@
   void DatabaseLoadComplete();
 
   // Called on the database thread to add/remove chunks and host keys.
-  void AddDatabaseChunks(const std::string& list,
-                         scoped_ptr<ScopedVector<SBChunkData> > chunks,
-                         AddChunksCallback callback);
+  void AddDatabaseChunks(
+      const std::string& list,
+      scoped_ptr<std::vector<scoped_ptr<SBChunkData>>> chunks,
+      AddChunksCallback callback);
 
   void DeleteDatabaseChunks(
       scoped_ptr<std::vector<SBChunkDelete> > chunk_deletes);
@@ -297,7 +298,7 @@
   void UpdateFinished(bool success) override;
   void GetChunks(GetChunksCallback callback) override;
   void AddChunks(const std::string& list,
-                 scoped_ptr<ScopedVector<SBChunkData>> chunks,
+                 scoped_ptr<std::vector<scoped_ptr<SBChunkData>>> chunks,
                  AddChunksCallback callback) override;
   void DeleteChunks(
       scoped_ptr<std::vector<SBChunkDelete>> chunk_deletes) override;
diff --git a/chrome/browser/safe_browsing/protocol_manager.cc b/chrome/browser/safe_browsing/protocol_manager.cc
index ada474d..e746763 100644
--- a/chrome/browser/safe_browsing/protocol_manager.cc
+++ b/chrome/browser/safe_browsing/protocol_manager.cc
@@ -6,7 +6,6 @@
 
 #include "base/environment.h"
 #include "base/logging.h"
-#include "base/memory/scoped_vector.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/metrics/sparse_histogram.h"
 #include "base/profiler/scoped_tracker.h"
@@ -457,8 +456,8 @@
                           base::Time::Now() - chunk_request_start_);
 
       const ChunkUrl chunk_url = chunk_request_urls_.front();
-      scoped_ptr<ScopedVector<SBChunkData>> chunks(
-          new ScopedVector<SBChunkData>);
+      scoped_ptr<std::vector<scoped_ptr<SBChunkData>>> chunks(
+          new std::vector<scoped_ptr<SBChunkData>>);
       UMA_HISTOGRAM_COUNTS("SB2.ChunkSize", length);
       update_size_ += length;
       if (!ParseChunk(data, length, chunks.get()))
diff --git a/chrome/browser/safe_browsing/protocol_manager.h b/chrome/browser/safe_browsing/protocol_manager.h
index 71088ef..1d33c52 100644
--- a/chrome/browser/safe_browsing/protocol_manager.h
+++ b/chrome/browser/safe_browsing/protocol_manager.h
@@ -432,9 +432,10 @@
 
   // Add new chunks to the database. Invokes |callback| when complete, but must
   // call at a later time.
-  virtual void AddChunks(const std::string& list,
-                         scoped_ptr<ScopedVector<SBChunkData> > chunks,
-                         AddChunksCallback callback) = 0;
+  virtual void AddChunks(
+      const std::string& list,
+      scoped_ptr<std::vector<scoped_ptr<SBChunkData>>> chunks,
+      AddChunksCallback callback) = 0;
 
   // Delete chunks from the database.
   virtual void DeleteChunks(
diff --git a/chrome/browser/safe_browsing/protocol_manager_unittest.cc b/chrome/browser/safe_browsing/protocol_manager_unittest.cc
index 10a366c..60bd467 100644
--- a/chrome/browser/safe_browsing/protocol_manager_unittest.cc
+++ b/chrome/browser/safe_browsing/protocol_manager_unittest.cc
@@ -3,8 +3,9 @@
 // found in the LICENSE file.
 //
 
+#include <vector>
+
 #include "base/memory/scoped_ptr.h"
-#include "base/memory/scoped_vector.h"
 #include "base/strings/stringprintf.h"
 #include "base/test/test_simple_task_runner.h"
 #include "base/thread_task_runner_handle.h"
@@ -328,11 +329,12 @@
   // gmock does not work with scoped_ptr<> at this time.  Add a local method to
   // mock, then call that from an override.  Beware of object ownership when
   // making changes here.
-  MOCK_METHOD3(AddChunksRaw, void(const std::string& lists,
-                                  const ScopedVector<SBChunkData>& chunks,
-                                  AddChunksCallback));
+  MOCK_METHOD3(AddChunksRaw,
+               void(const std::string& lists,
+                    const std::vector<scoped_ptr<SBChunkData>>& chunks,
+                    AddChunksCallback));
   void AddChunks(const std::string& list,
-                 scoped_ptr<ScopedVector<SBChunkData>> chunks,
+                 scoped_ptr<std::vector<scoped_ptr<SBChunkData>>> chunks,
                  AddChunksCallback callback) override {
     AddChunksRaw(list, *chunks, callback);
   }
@@ -362,7 +364,7 @@
 // SafeBrowsingProtocolManagerDelegate contract.
 void HandleAddChunks(
     const std::string& unused_list,
-    const ScopedVector<SBChunkData>& chunks,
+    const std::vector<scoped_ptr<SBChunkData>>& chunks,
     SafeBrowsingProtocolManagerDelegate::AddChunksCallback callback) {
   scoped_refptr<base::SingleThreadTaskRunner> task_runner(
       base::ThreadTaskRunnerHandle::Get());
diff --git a/chrome/browser/safe_browsing/protocol_parser.cc b/chrome/browser/safe_browsing/protocol_parser.cc
index 1ba1e339..8f44267d 100644
--- a/chrome/browser/safe_browsing/protocol_parser.cc
+++ b/chrome/browser/safe_browsing/protocol_parser.cc
@@ -350,7 +350,7 @@
 // CHUNKDATA = Encoded ChunkData protocol message
 bool ParseChunk(const char* data,
                 size_t length,
-                ScopedVector<SBChunkData>* chunks) {
+                std::vector<scoped_ptr<SBChunkData>>* chunks) {
   BufferReader reader(data, length);
 
   while (!reader.empty()) {
@@ -366,7 +366,7 @@
     if (!chunk->ParseFrom(reinterpret_cast<const unsigned char*>(p), l))
       return false;
 
-    chunks->push_back(chunk.release());
+    chunks->push_back(chunk.Pass());
   }
 
   DCHECK(reader.empty());
diff --git a/chrome/browser/safe_browsing/protocol_parser.h b/chrome/browser/safe_browsing/protocol_parser.h
index 4b7bf6c..9509734 100644
--- a/chrome/browser/safe_browsing/protocol_parser.h
+++ b/chrome/browser/safe_browsing/protocol_parser.h
@@ -14,7 +14,6 @@
 #include <vector>
 
 #include "base/basictypes.h"
-#include "base/memory/scoped_vector.h"
 #include "chrome/browser/safe_browsing/safe_browsing_util.h"
 
 namespace base {
@@ -44,7 +43,7 @@
 // results should be discarded.
 bool ParseChunk(const char* chunk_data,
                 size_t chunk_len,
-                ScopedVector<SBChunkData>* chunks);
+                std::vector<scoped_ptr<SBChunkData>>* chunks);
 
 // Parse body of "HTTP Response for Full-Length Hashes", returning the list of
 // full hashes.  Returns |false| if the data could not be parsed correctly, in
diff --git a/chrome/browser/safe_browsing/protocol_parser_unittest.cc b/chrome/browser/safe_browsing/protocol_parser_unittest.cc
index 5d4993f..3258650 100644
--- a/chrome/browser/safe_browsing/protocol_parser_unittest.cc
+++ b/chrome/browser/safe_browsing/protocol_parser_unittest.cc
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include <string>
+#include <vector>
 
 #include "base/strings/stringprintf.h"
 #include "base/time/time.h"
@@ -35,7 +36,7 @@
     '9', '9', '9', '9',
   };
 
-  ScopedVector<SBChunkData> chunks;
+  std::vector<scoped_ptr<SBChunkData>> chunks;
   EXPECT_TRUE(ParseChunk(kRawAddChunk, sizeof(kRawAddChunk), &chunks));
   ASSERT_EQ(1U, chunks.size());
   EXPECT_EQ(1, chunks[0]->ChunkNumber());
@@ -80,7 +81,7 @@
     full_hash2.full_hash[i] = (i % 2) ? '3' : '2';
   }
 
-  ScopedVector<SBChunkData> chunks;
+  std::vector<scoped_ptr<SBChunkData>> chunks;
   EXPECT_TRUE(ParseChunk(kRawAddChunk, sizeof(kRawAddChunk), &chunks));
   ASSERT_EQ(1U, chunks.size());
   EXPECT_EQ(1, chunks[0]->ChunkNumber());
@@ -120,7 +121,7 @@
     'g', 'g', 'g', 'g',
   };
 
-  ScopedVector<SBChunkData> chunks;
+  std::vector<scoped_ptr<SBChunkData>> chunks;
   EXPECT_TRUE(ParseChunk(kRawAddChunk, sizeof(kRawAddChunk), &chunks));
   ASSERT_EQ(2U, chunks.size());
 
@@ -160,7 +161,7 @@
     '3', '3', '3', '3',
   };
 
-  ScopedVector<SBChunkData> chunks;
+  std::vector<scoped_ptr<SBChunkData>> chunks;
   EXPECT_FALSE(ParseChunk(kRawAddChunk, sizeof(kRawAddChunk), &chunks));
 }
 
@@ -181,7 +182,7 @@
     '0', '1', '0', '1', '0', '1', '0', '1',
   };
 
-  ScopedVector<SBChunkData> chunks;
+  std::vector<scoped_ptr<SBChunkData>> chunks;
   EXPECT_FALSE(ParseChunk(kRawAddChunk, sizeof(kRawAddChunk), &chunks));
 }
 
@@ -198,7 +199,7 @@
     '3', '3', '3', '3',
   };
 
-  ScopedVector<SBChunkData> chunks;
+  std::vector<scoped_ptr<SBChunkData>> chunks;
   EXPECT_FALSE(ParseChunk(kRawAddChunk, sizeof(kRawAddChunk), &chunks));
 }
 
@@ -219,7 +220,7 @@
     '\x07', '\x09',            // varint 7, varint 9
   };
 
-  ScopedVector<SBChunkData> chunks;
+  std::vector<scoped_ptr<SBChunkData>> chunks;
   EXPECT_TRUE(ParseChunk(kRawSubChunk, sizeof(kRawSubChunk), &chunks));
   ASSERT_EQ(1U, chunks.size());
   EXPECT_EQ(3, chunks[0]->ChunkNumber());
@@ -268,7 +269,7 @@
     full_hash2.full_hash[i] = i % 2 ? '3' : '2';
   }
 
-  ScopedVector<SBChunkData> chunks;
+  std::vector<scoped_ptr<SBChunkData>> chunks;
   EXPECT_TRUE(ParseChunk(kRawSubChunk, sizeof(kRawSubChunk), &chunks));
   ASSERT_EQ(1U, chunks.size());
   EXPECT_EQ(2, chunks[0]->ChunkNumber());
@@ -551,7 +552,7 @@
     '\x02',                    // chunk_number varint 2
   };
 
-  ScopedVector<SBChunkData> chunks;
+  std::vector<scoped_ptr<SBChunkData>> chunks;
   EXPECT_TRUE(ParseChunk(kEmptyAddChunk, sizeof(kEmptyAddChunk), &chunks));
   ASSERT_EQ(1U, chunks.size());
   EXPECT_EQ(2, chunks[0]->ChunkNumber());
@@ -622,7 +623,7 @@
     '\x01',                    // enum ChunkType == SUB
   };
 
-  ScopedVector<SBChunkData> chunks;
+  std::vector<scoped_ptr<SBChunkData>> chunks;
   EXPECT_TRUE(ParseChunk(kEmptySubChunk, sizeof(kEmptySubChunk), &chunks));
   ASSERT_EQ(1U, chunks.size());
   EXPECT_EQ(2, chunks[0]->ChunkNumber());
diff --git a/chrome/browser/safe_browsing/safe_browsing_database.cc b/chrome/browser/safe_browsing/safe_browsing_database.cc
index c79d05d..8a8dddf 100644
--- a/chrome/browser/safe_browsing/safe_browsing_database.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_database.cc
@@ -1062,7 +1062,7 @@
 
 void SafeBrowsingDatabaseNew::InsertChunks(
     const std::string& list_name,
-    const std::vector<SBChunkData*>& chunks) {
+    const std::vector<scoped_ptr<SBChunkData>>& chunks) {
   DCHECK(db_task_runner_->RunsTasksOnCurrentThread());
 
   if (db_state_manager_.corruption_detected() || chunks.empty())
@@ -1082,11 +1082,11 @@
   // TODO(shess): I believe that the list is always add or sub.  Can this use
   // that productively?
   store->BeginChunk();
-  for (size_t i = 0; i < chunks.size(); ++i) {
-    if (chunks[i]->IsAdd()) {
-      InsertAddChunk(store, list_id, *chunks[i]);
-    } else if (chunks[i]->IsSub()) {
-      InsertSubChunk(store, list_id, *chunks[i]);
+  for (const auto& chunk : chunks) {
+    if (chunk->IsAdd()) {
+      InsertAddChunk(store, list_id, *chunk);
+    } else if (chunk->IsSub()) {
+      InsertSubChunk(store, list_id, *chunk);
     } else {
       NOTREACHED();
     }
diff --git a/chrome/browser/safe_browsing/safe_browsing_database.h b/chrome/browser/safe_browsing/safe_browsing_database.h
index 5476256..17c7b8f 100644
--- a/chrome/browser/safe_browsing/safe_browsing_database.h
+++ b/chrome/browser/safe_browsing/safe_browsing_database.h
@@ -169,8 +169,9 @@
   // UpdateFinished().  If it returns false, the caller MUST NOT call
   // the other functions.
   virtual bool UpdateStarted(std::vector<SBListChunkRanges>* lists) = 0;
-  virtual void InsertChunks(const std::string& list_name,
-                            const std::vector<SBChunkData*>& chunks) = 0;
+  virtual void InsertChunks(
+      const std::string& list_name,
+      const std::vector<scoped_ptr<SBChunkData>>& chunks) = 0;
   virtual void DeleteChunks(
       const std::vector<SBChunkDelete>& chunk_deletes) = 0;
   virtual void UpdateFinished(bool update_succeeded) = 0;
@@ -333,8 +334,9 @@
                                  std::vector<SBPrefix>* prefix_hits) override;
   bool ContainsMalwareIP(const std::string& ip_address) override;
   bool UpdateStarted(std::vector<SBListChunkRanges>* lists) override;
-  void InsertChunks(const std::string& list_name,
-                    const std::vector<SBChunkData*>& chunks) override;
+  void InsertChunks(
+      const std::string& list_name,
+      const std::vector<scoped_ptr<SBChunkData>>& chunks) override;
   void DeleteChunks(const std::vector<SBChunkDelete>& chunk_deletes) override;
   void UpdateFinished(bool update_succeeded) override;
   void CacheHashResults(const std::vector<SBPrefix>& prefixes,
diff --git a/chrome/browser/safe_browsing/safe_browsing_database_unittest.cc b/chrome/browser/safe_browsing/safe_browsing_database_unittest.cc
index b76173ca3..7264c9f 100644
--- a/chrome/browser/safe_browsing/safe_browsing_database_unittest.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_database_unittest.cc
@@ -9,7 +9,6 @@
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/logging.h"
-#include "base/memory/scoped_vector.h"
 #include "base/message_loop/message_loop.h"
 #include "base/sha1.h"
 #include "base/strings/string_number_conversions.h"
@@ -62,12 +61,12 @@
 }
 
 // Helper to build a chunk.  Caller takes ownership.
-SBChunkData* BuildChunk(int chunk_number,
-                        ChunkData::ChunkType chunk_type,
-                        ChunkData::PrefixType prefix_type,
-                        const void* data,
-                        size_t data_size,
-                        const std::vector<int>& add_chunk_numbers) {
+scoped_ptr<SBChunkData> BuildChunk(int chunk_number,
+                                   ChunkData::ChunkType chunk_type,
+                                   ChunkData::PrefixType prefix_type,
+                                   const void* data,
+                                   size_t data_size,
+                                   const std::vector<int>& add_chunk_numbers) {
   scoped_ptr<ChunkData> raw_data(new ChunkData);
   raw_data->set_chunk_number(chunk_number);
   raw_data->set_chunk_type(chunk_type);
@@ -78,25 +77,25 @@
     raw_data->add_add_numbers(add_chunk_numbers[i]);
   }
 
-  return new SBChunkData(raw_data.release());
+  return make_scoped_ptr(new SBChunkData(raw_data.Pass()));
 }
 
 // Create add chunk with a single prefix.
-SBChunkData* AddChunkPrefix(int chunk_number, SBPrefix prefix) {
+scoped_ptr<SBChunkData> AddChunkPrefix(int chunk_number, SBPrefix prefix) {
   return BuildChunk(chunk_number, ChunkData::ADD, ChunkData::PREFIX_4B, &prefix,
                     sizeof(prefix), std::vector<int>());
 }
 
 // Create add chunk with a single prefix generated from |value|.
-SBChunkData* AddChunkPrefixValue(int chunk_number,
-                                 const std::string& value) {
+scoped_ptr<SBChunkData> AddChunkPrefixValue(int chunk_number,
+                                            const std::string& value) {
   return AddChunkPrefix(chunk_number, SBPrefixForString(value));
 }
 
 // Generate an add chunk with two prefixes.
-SBChunkData* AddChunkPrefix2Value(int chunk_number,
-                                  const std::string& value1,
-                                  const std::string& value2) {
+scoped_ptr<SBChunkData> AddChunkPrefix2Value(int chunk_number,
+                                             const std::string& value1,
+                                             const std::string& value2) {
   const SBPrefix prefixes[2] = {
     SBPrefixForString(value1),
     SBPrefixForString(value2),
@@ -106,11 +105,11 @@
 }
 
 // Generate an add chunk with four prefixes.
-SBChunkData* AddChunkPrefix4Value(int chunk_number,
-                                  const std::string& value1,
-                                  const std::string& value2,
-                                  const std::string& value3,
-                                  const std::string& value4) {
+scoped_ptr<SBChunkData> AddChunkPrefix4Value(int chunk_number,
+                                             const std::string& value1,
+                                             const std::string& value2,
+                                             const std::string& value3,
+                                             const std::string& value4) {
   const SBPrefix prefixes[4] = {
     SBPrefixForString(value1),
     SBPrefixForString(value2),
@@ -122,22 +121,23 @@
 }
 
 // Generate an add chunk with a full hash.
-SBChunkData* AddChunkFullHash(int chunk_number, SBFullHash full_hash) {
+scoped_ptr<SBChunkData> AddChunkFullHash(int chunk_number,
+                                         SBFullHash full_hash) {
   return BuildChunk(chunk_number, ChunkData::ADD, ChunkData::FULL_32B,
                     &full_hash, sizeof(full_hash), std::vector<int>());
 }
 
 // Generate an add chunk with a full hash generated from |value|.
-SBChunkData* AddChunkFullHashValue(int chunk_number,
-                                   const std::string& value) {
+scoped_ptr<SBChunkData> AddChunkFullHashValue(int chunk_number,
+                                              const std::string& value) {
   return AddChunkFullHash(chunk_number,
                           SBFullHashForString(value));
 }
 
 // Generate an add chunk with two full hashes.
-SBChunkData* AddChunkFullHash2Value(int chunk_number,
-                                   const std::string& value1,
-                                   const std::string& value2) {
+scoped_ptr<SBChunkData> AddChunkFullHash2Value(int chunk_number,
+                                               const std::string& value1,
+                                               const std::string& value2) {
   const SBFullHash full_hashes[2] = {
     SBFullHashForString(value1),
     SBFullHashForString(value2),
@@ -147,20 +147,20 @@
 }
 
 // Generate a sub chunk with a prefix generated from |value|.
-SBChunkData* SubChunkPrefixValue(int chunk_number,
-                                 const std::string& value,
-                                 int add_chunk_number) {
+scoped_ptr<SBChunkData> SubChunkPrefixValue(int chunk_number,
+                                            const std::string& value,
+                                            int add_chunk_number) {
   const SBPrefix prefix = SBPrefixForString(value);
   return BuildChunk(chunk_number, ChunkData::SUB, ChunkData::PREFIX_4B, &prefix,
                     sizeof(prefix), std::vector<int>(1, add_chunk_number));
 }
 
 // Generate a sub chunk with two prefixes.
-SBChunkData* SubChunkPrefix2Value(int chunk_number,
-                                  const std::string& value1,
-                                  int add_chunk_number1,
-                                  const std::string& value2,
-                                  int add_chunk_number2) {
+scoped_ptr<SBChunkData> SubChunkPrefix2Value(int chunk_number,
+                                             const std::string& value1,
+                                             int add_chunk_number1,
+                                             const std::string& value2,
+                                             int add_chunk_number2) {
   const SBPrefix prefixes[2] = {
     SBPrefixForString(value1),
     SBPrefixForString(value2),
@@ -173,27 +173,27 @@
 }
 
 // Generate a sub chunk with a full hash.
-SBChunkData* SubChunkFullHash(int chunk_number,
-                              SBFullHash full_hash,
-                              int add_chunk_number) {
+scoped_ptr<SBChunkData> SubChunkFullHash(int chunk_number,
+                                         SBFullHash full_hash,
+                                         int add_chunk_number) {
   return BuildChunk(chunk_number, ChunkData::SUB, ChunkData::FULL_32B,
                     &full_hash, sizeof(full_hash),
                     std::vector<int>(1, add_chunk_number));
 }
 
 // Generate a sub chunk with a full hash generated from |value|.
-SBChunkData* SubChunkFullHashValue(int chunk_number,
-                                   const std::string& value,
-                                   int add_chunk_number) {
+scoped_ptr<SBChunkData> SubChunkFullHashValue(int chunk_number,
+                                              const std::string& value,
+                                              int add_chunk_number) {
   return SubChunkFullHash(chunk_number,
                           SBFullHashForString(value),
                           add_chunk_number);
 }
 
 // Generate an add chunk with a single full hash for the ip blacklist.
-SBChunkData* AddChunkHashedIpValue(int chunk_number,
-                                   const std::string& ip_str,
-                                   size_t prefix_size) {
+scoped_ptr<SBChunkData> AddChunkHashedIpValue(int chunk_number,
+                                              const std::string& ip_str,
+                                              size_t prefix_size) {
   const std::string full_hash_str = HashedIpPrefix(ip_str, prefix_size);
   EXPECT_EQ(sizeof(SBFullHash), full_hash_str.size());
   SBFullHash full_hash;
@@ -331,14 +331,14 @@
 // Tests retrieving list name information.
 TEST_F(SafeBrowsingDatabaseTest, BrowseListsInfo) {
   std::vector<SBListChunkRanges> lists;
-  ScopedVector<SBChunkData> chunks;
+  std::vector<scoped_ptr<SBChunkData>> chunks;
 
   chunks.push_back(AddChunkPrefixValue(1, "www.evil.com/malware.html"));
   chunks.push_back(AddChunkPrefixValue(2, "www.foo.com/malware.html"));
   chunks.push_back(AddChunkPrefixValue(3, "www.whatever.com/malware.html"));
 
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  database_->InsertChunks(kMalwareList, chunks.get());
+  database_->InsertChunks(kMalwareList, chunks);
   database_->UpdateFinished(true);
 
   GetListsInfo(&lists);
@@ -352,7 +352,7 @@
   chunks.push_back(SubChunkPrefixValue(7, "www.subbed.com/noteveil1.html", 19));
 
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  database_->InsertChunks(kMalwareList, chunks.get());
+  database_->InsertChunks(kMalwareList, chunks);
   database_->UpdateFinished(true);
 
   GetListsInfo(&lists);
@@ -378,7 +378,7 @@
       SubChunkPrefixValue(201, "www.phishy2.com/notevil1.html", 1999));
 
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  database_->InsertChunks(kPhishingList, chunks.get());
+  database_->InsertChunks(kPhishingList, chunks);
   database_->UpdateFinished(true);
 
   GetListsInfo(&lists);
@@ -392,50 +392,50 @@
 }
 
 TEST_F(SafeBrowsingDatabaseTest, ListNames) {
-  ScopedVector<SBChunkData> chunks;
+  std::vector<scoped_ptr<SBChunkData>> chunks;
 
   std::vector<SBListChunkRanges> lists;
   ASSERT_TRUE(database_->UpdateStarted(&lists));
 
   // Insert malware, phish, binurl and bindownload add chunks.
   chunks.push_back(AddChunkPrefixValue(1, "www.evil.com/malware.html"));
-  database_->InsertChunks(kMalwareList, chunks.get());
+  database_->InsertChunks(kMalwareList, chunks);
 
   chunks.clear();
   chunks.push_back(AddChunkPrefixValue(2, "www.foo.com/malware.html"));
-  database_->InsertChunks(kPhishingList, chunks.get());
+  database_->InsertChunks(kPhishingList, chunks);
 
   chunks.clear();
   chunks.push_back(AddChunkPrefixValue(3, "www.whatever.com/download.html"));
-  database_->InsertChunks(kBinUrlList, chunks.get());
+  database_->InsertChunks(kBinUrlList, chunks);
 
   chunks.clear();
   chunks.push_back(AddChunkFullHashValue(5, "www.forwhitelist.com/a.html"));
-  database_->InsertChunks(kCsdWhiteList, chunks.get());
+  database_->InsertChunks(kCsdWhiteList, chunks);
 
   chunks.clear();
   chunks.push_back(AddChunkFullHashValue(6, "www.download.com/"));
-  database_->InsertChunks(kDownloadWhiteList, chunks.get());
+  database_->InsertChunks(kDownloadWhiteList, chunks);
 
   chunks.clear();
   chunks.push_back(AddChunkFullHashValue(7, "www.inclusion.com/"));
   database_->InsertChunks(kInclusionWhitelist,
-                          chunks.get());
+                          chunks);
 
   chunks.clear();
   chunks.push_back(AddChunkFullHashValue(8,
                                          "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
                                          "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
   database_->InsertChunks(kExtensionBlacklist,
-                          chunks.get());
+                          chunks);
 
   chunks.clear();
   chunks.push_back(AddChunkHashedIpValue(10, "::ffff:192.168.1.0", 120));
-  database_->InsertChunks(kIPBlacklist, chunks.get());
+  database_->InsertChunks(kIPBlacklist, chunks);
 
   chunks.clear();
   chunks.push_back(AddChunkPrefixValue(11, "www.unwanted.com/software.html"));
-  database_->InsertChunks(kUnwantedUrlList, chunks.get());
+  database_->InsertChunks(kUnwantedUrlList, chunks);
 
   database_->UpdateFinished(true);
 
@@ -495,7 +495,7 @@
                  test_case.test_list_name);
 
     std::vector<SBListChunkRanges> lists;
-    ScopedVector<SBChunkData> chunks;
+    std::vector<scoped_ptr<SBChunkData>> chunks;
 
     chunks.push_back(AddChunkPrefix2Value(1,
                                           "www.evil.com/phishing.html",
@@ -509,7 +509,7 @@
     chunks.push_back(AddChunkFullHashValue(7, "www.evil.com/evil.html"));
 
     ASSERT_TRUE(database_->UpdateStarted(&lists));
-    database_->InsertChunks(test_case.test_list_name, chunks.get());
+    database_->InsertChunks(test_case.test_list_name, chunks);
     database_->UpdateFinished(true);
 
     // Make sure they were added correctly.
@@ -567,7 +567,7 @@
                                           "www.evil.com/phishing.html",
                                           "www.evil.com/malware.html"));
     ASSERT_TRUE(database_->UpdateStarted(&lists));
-    database_->InsertChunks(test_case.test_list_name, chunks.get());
+    database_->InsertChunks(test_case.test_list_name, chunks);
     database_->UpdateFinished(true);
 
     GetListsInfo(&lists);
@@ -581,7 +581,7 @@
     chunks.clear();
     chunks.push_back(SubChunkPrefixValue(4, "www.evil.com/notevil1.html", 2));
     ASSERT_TRUE(database_->UpdateStarted(&lists));
-    database_->InsertChunks(test_case.test_list_name, chunks.get());
+    database_->InsertChunks(test_case.test_list_name, chunks);
     database_->UpdateFinished(true);
 
     EXPECT_TRUE((database_.get()->*test_case.test_list_contains_bad_url)(
@@ -617,7 +617,7 @@
     chunks.push_back(SubChunkPrefixValue(4, "www.evil.com/notevil1.html", 2));
 
     ASSERT_TRUE(database_->UpdateStarted(&lists));
-    database_->InsertChunks(test_case.test_list_name, chunks.get());
+    database_->InsertChunks(test_case.test_list_name, chunks);
     database_->UpdateFinished(true);
 
     GetListsInfo(&lists);
@@ -654,7 +654,7 @@
     chunks.clear();
     chunks.push_back(AddChunkPrefixValue(44, "www.redherring.com/index.html"));
     ASSERT_TRUE(database_->UpdateStarted(&lists));
-    database_->InsertChunks(test_case.test_list_name, chunks.get());
+    database_->InsertChunks(test_case.test_list_name, chunks);
 
     // Now remove the dummy entry.  If there are any problems with the
     // transactions, asserts will fire.
@@ -679,7 +679,7 @@
                                           "www.notevilanymore.com/good.html",
                                           10));
     ASSERT_TRUE(database_->UpdateStarted(&lists));
-    database_->InsertChunks(test_case.test_list_name, chunks.get());
+    database_->InsertChunks(test_case.test_list_name, chunks);
     database_->UpdateFinished(true);
 
     EXPECT_FALSE((database_.get()->*test_case.test_list_contains_bad_url)(
@@ -694,7 +694,7 @@
                                           "www.notevilanymore.com/index.html",
                                           "www.notevilanymore.com/good.html"));
     ASSERT_TRUE(database_->UpdateStarted(&lists));
-    database_->InsertChunks(test_case.test_list_name, chunks.get());
+    database_->InsertChunks(test_case.test_list_name, chunks);
     database_->UpdateFinished(true);
 
     EXPECT_FALSE((database_.get()->*test_case.test_list_contains_bad_url)(
@@ -731,7 +731,7 @@
 // Test adding zero length chunks to the database.
 TEST_F(SafeBrowsingDatabaseTest, ZeroSizeChunk) {
   std::vector<SBListChunkRanges> lists;
-  ScopedVector<SBChunkData> chunks;
+  std::vector<scoped_ptr<SBChunkData>> chunks;
 
   // Populate with a couple of normal chunks.
   chunks.push_back(AddChunkPrefix2Value(1,
@@ -742,7 +742,7 @@
                                         "www.random.com/random2.html"));
 
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  database_->InsertChunks(kMalwareList, chunks.get());
+  database_->InsertChunks(kMalwareList, chunks);
   database_->UpdateFinished(true);
 
   // Add an empty ADD and SUB chunk.
@@ -759,7 +759,7 @@
                               std::vector<int>()));
 
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  database_->InsertChunks(kMalwareList, chunks.get());
+  database_->InsertChunks(kMalwareList, chunks);
   database_->UpdateFinished(true);
 
   GetListsInfo(&lists);
@@ -777,7 +777,7 @@
   chunks.push_back(AddChunkPrefixValue(22, "www.notempty.com/full2.html"));
 
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  database_->InsertChunks(kMalwareList, chunks.get());
+  database_->InsertChunks(kMalwareList, chunks);
   database_->UpdateFinished(true);
 
   std::vector<SBPrefix> prefix_hits;
@@ -818,14 +818,14 @@
 // Utility function for setting up the database for the caching test.
 void SafeBrowsingDatabaseTest::PopulateDatabaseForCacheTest() {
   // Add a couple prefixes.
-  ScopedVector<SBChunkData> chunks;
+  std::vector<scoped_ptr<SBChunkData>> chunks;
   chunks.push_back(AddChunkPrefix2Value(1,
                                         "www.evil.com/phishing.html",
                                         "www.evil.com/malware.html"));
 
   std::vector<SBListChunkRanges> lists;
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  database_->InsertChunks(kMalwareList, chunks.get());
+  database_->InsertChunks(kMalwareList, chunks);
   database_->UpdateFinished(true);
 
   // Cache should be cleared after updating.
@@ -886,12 +886,12 @@
   cache_hits.clear();
 
   // Test removing a prefix via a sub chunk.
-  ScopedVector<SBChunkData> chunks;
+  std::vector<scoped_ptr<SBChunkData>> chunks;
   chunks.push_back(SubChunkPrefixValue(2, "www.evil.com/phishing.html", 1));
 
   std::vector<SBListChunkRanges> lists;
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  database_->InsertChunks(kMalwareList, chunks.get());
+  database_->InsertChunks(kMalwareList, chunks);
   database_->UpdateFinished(true);
 
   // This prefix should still be there, but cached fullhash should be gone.
@@ -1002,7 +1002,7 @@
                                           "www.fullevil.com/bad1.html",
                                           "www.fullevil.com/bad2.html"));
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  database_->InsertChunks(kMalwareList, chunks.get());
+  database_->InsertChunks(kMalwareList, chunks);
   database_->UpdateFinished(true);
 
   EXPECT_TRUE(database_->ContainsBrowseUrl(
@@ -1027,7 +1027,7 @@
                                          "www.fullevil.com/bad1.html",
                                          20));
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  database_->InsertChunks(kMalwareList, chunks.get());
+  database_->InsertChunks(kMalwareList, chunks);
   database_->UpdateFinished(true);
 
   EXPECT_FALSE(database_->ContainsBrowseUrl(
@@ -1060,9 +1060,9 @@
             SBPrefixForString(kExampleCollision));
   ASSERT_TRUE(database_->UpdateStarted(&lists));
   {
-    ScopedVector<SBChunkData> chunks;
+    std::vector<scoped_ptr<SBChunkData>> chunks;
     chunks.push_back(AddChunkPrefixValue(21, kExampleCollision));
-    database_->InsertChunks(kMalwareList, chunks.get());
+    database_->InsertChunks(kMalwareList, chunks);
   }
   database_->UpdateFinished(true);
 
@@ -1110,7 +1110,7 @@
   database_->UpdateFinished(true);
 
   // Create a sub chunk to insert.
-  ScopedVector<SBChunkData> chunks;
+  std::vector<scoped_ptr<SBChunkData>> chunks;
   chunks.push_back(SubChunkPrefixValue(7,
                                        "www.subbed.com/notevil1.html",
                                        19));
@@ -1131,7 +1131,7 @@
 
     // Start an update.  The insert will fail due to corruption.
     ASSERT_TRUE(database_->UpdateStarted(&lists));
-    database_->InsertChunks(kMalwareList, chunks.get());
+    database_->InsertChunks(kMalwareList, chunks);
     database_->UpdateFinished(true);
 
     // Database file still exists until the corruption handler has run.
@@ -1147,7 +1147,7 @@
 
   // Run the update again successfully.
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  database_->InsertChunks(kMalwareList, chunks.get());
+  database_->InsertChunks(kMalwareList, chunks);
   database_->UpdateFinished(true);
   EXPECT_TRUE(base::PathExists(database_filename_));
 
@@ -1160,12 +1160,12 @@
   const char kEvil1Url2[] = "www.evil1.com/download2.html";
 
   // Add a simple chunk with one hostkey for download url list.
-  ScopedVector<SBChunkData> chunks;
+  std::vector<scoped_ptr<SBChunkData>> chunks;
   chunks.push_back(AddChunkPrefix2Value(1, kEvil1Url1, kEvil1Url2));
 
   std::vector<SBListChunkRanges> lists;
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  database_->InsertChunks(kBinUrlList, chunks.get());
+  database_->InsertChunks(kBinUrlList, chunks);
   database_->UpdateFinished(true);
 
   std::vector<SBPrefix> prefix_hits;
@@ -1332,7 +1332,7 @@
               kGoodString));
     }
 
-    ScopedVector<SBChunkData> chunks;
+    std::vector<scoped_ptr<SBChunkData>> chunks;
 
     // Add a few test chunks to the whitelist under test.
     chunks.push_back(AddChunkFullHash2Value(1, kGood1Url1, kGood1Url2));
@@ -1343,7 +1343,7 @@
 
     std::vector<SBListChunkRanges> lists;
     ASSERT_TRUE(database_->UpdateStarted(&lists));
-    database_->InsertChunks(test_case.test_list_name, chunks.get());
+    database_->InsertChunks(test_case.test_list_name, chunks);
     database_->UpdateFinished(true);
 
     EXPECT_FALSE(
@@ -1413,7 +1413,7 @@
           15, "sb-ssl.google.com/safebrowsing/csd/killswitch_malware"));
 
       ASSERT_TRUE(database_->UpdateStarted(&lists));
-      database_->InsertChunks(kCsdWhiteList, chunks.get());
+      database_->InsertChunks(kCsdWhiteList, chunks);
       database_->UpdateFinished(true);
 
       EXPECT_TRUE(database_->IsMalwareIPMatchKillSwitchOn());
@@ -1428,7 +1428,7 @@
         5, "sb-ssl.google.com/safebrowsing/csd/killswitch"));
 
     ASSERT_TRUE(database_->UpdateStarted(&lists));
-    database_->InsertChunks(test_case.test_list_name, chunks.get());
+    database_->InsertChunks(test_case.test_list_name, chunks);
     database_->UpdateFinished(true);
 
     // Test CSD whitelist specific methods.
@@ -1468,7 +1468,7 @@
     }
 
     ASSERT_TRUE(database_->UpdateStarted(&lists));
-    database_->InsertChunks(test_case.test_list_name, chunks.get());
+    database_->InsertChunks(test_case.test_list_name, chunks);
     database_->UpdateFinished(true);
 
     if (test_case.test_list_name == kCsdWhiteList) {
@@ -1504,7 +1504,7 @@
 // Test to make sure we could insert chunk list that
 // contains entries for the same host.
 TEST_F(SafeBrowsingDatabaseTest, SameHostEntriesOkay) {
-  ScopedVector<SBChunkData> chunks;
+  std::vector<scoped_ptr<SBChunkData>> chunks;
 
   // Add a malware add chunk with two entries of the same host.
   chunks.push_back(AddChunkPrefix2Value(1,
@@ -1514,7 +1514,7 @@
   // Insert the testing chunks into database.
   std::vector<SBListChunkRanges> lists;
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  database_->InsertChunks(kMalwareList, chunks.get());
+  database_->InsertChunks(kMalwareList, chunks);
   database_->UpdateFinished(true);
 
   GetListsInfo(&lists);
@@ -1530,7 +1530,7 @@
                                         "www.evil.com/phishing2.html"));
 
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  database_->InsertChunks(kPhishingList, chunks.get());
+  database_->InsertChunks(kPhishingList, chunks);
   database_->UpdateFinished(true);
 
   GetListsInfo(&lists);
@@ -1559,14 +1559,14 @@
   chunks.clear();
   chunks.push_back(SubChunkPrefixValue(4, "www.evil.com/malware1.html", 1));
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  database_->InsertChunks(kMalwareList, chunks.get());
+  database_->InsertChunks(kMalwareList, chunks);
   database_->UpdateFinished(true);
 
   // Remove the prefix that added last.
   chunks.clear();
   chunks.push_back(SubChunkPrefixValue(5, "www.evil.com/phishing2.html", 47));
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  database_->InsertChunks(kPhishingList, chunks.get());
+  database_->InsertChunks(kPhishingList, chunks);
   database_->UpdateFinished(true);
 
   // Verify that the database contains urls expected.
@@ -1584,7 +1584,7 @@
 // This isn't a functionality requirement, but it is a useful
 // optimization.
 TEST_F(SafeBrowsingDatabaseTest, EmptyUpdate) {
-  ScopedVector<SBChunkData> chunks;
+  std::vector<scoped_ptr<SBChunkData>> chunks;
 
   base::FilePath filename = database_->BrowseDBFilename(database_filename_);
 
@@ -1592,7 +1592,7 @@
   std::vector<SBListChunkRanges> lists;
   ASSERT_TRUE(database_->UpdateStarted(&lists));
   chunks.push_back(AddChunkPrefixValue(1, "www.evil.com/malware.html"));
-  database_->InsertChunks(kMalwareList, chunks.get());
+  database_->InsertChunks(kMalwareList, chunks);
   database_->UpdateFinished(true);
 
   // Get an older time to reset the lastmod time for detecting whether
@@ -1609,7 +1609,7 @@
   ASSERT_TRUE(base::GetFileInfo(filename, &before_info));
   ASSERT_TRUE(database_->UpdateStarted(&lists));
   chunks.push_back(AddChunkPrefixValue(2, "www.foo.com/malware.html"));
-  database_->InsertChunks(kMalwareList, chunks.get());
+  database_->InsertChunks(kMalwareList, chunks);
   database_->UpdateFinished(true);
   ASSERT_TRUE(base::GetFileInfo(filename, &after_info));
   EXPECT_LT(before_info.last_modified, after_info.last_modified);
@@ -1642,9 +1642,9 @@
     std::vector<SBListChunkRanges> lists;
     ASSERT_TRUE(database_->UpdateStarted(&lists));
 
-    ScopedVector<SBChunkData> chunks;
+    std::vector<scoped_ptr<SBChunkData>> chunks;
     chunks.push_back(AddChunkPrefixValue(1, "www.evil.com/malware.html"));
-    database_->InsertChunks(kMalwareList, chunks.get());
+    database_->InsertChunks(kMalwareList, chunks);
     database_->UpdateFinished(true);
   }
 
@@ -1688,13 +1688,13 @@
       SBFullHashForPrefixAndSuffix(kPrefix2, "\x01");
 
   // Insert prefix kPrefix1 and kPrefix2 into database.
-  ScopedVector<SBChunkData> chunks;
+  std::vector<scoped_ptr<SBChunkData>> chunks;
   chunks.push_back(AddChunkPrefix(1, kPrefix1));
   chunks.push_back(AddChunkPrefix(2, kPrefix2));
 
   std::vector<SBListChunkRanges> lists;
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  database_->InsertChunks(kMalwareList, chunks.get());
+  database_->InsertChunks(kMalwareList, chunks);
   database_->UpdateFinished(true);
 
   {
@@ -1743,13 +1743,13 @@
       SBFullHashForPrefixAndSuffix(kPrefix3, "\x01");
 
   // Insert prefix kPrefix1 and kPrefix2 into database.
-  ScopedVector<SBChunkData> chunks;
+  std::vector<scoped_ptr<SBChunkData>> chunks;
   chunks.push_back(AddChunkPrefix(1, kPrefix1));
   chunks.push_back(AddChunkPrefix(2, kPrefix2));
 
   std::vector<SBListChunkRanges> lists;
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  database_->InsertChunks(kMalwareList, chunks.get());
+  database_->InsertChunks(kMalwareList, chunks);
   database_->UpdateFinished(true);
 
   {
@@ -1888,13 +1888,13 @@
       SBFullHashForPrefixAndSuffix(kPrefix1, "\x03");
 
   // Insert two full hashes with a shared prefix.
-  ScopedVector<SBChunkData> chunks;
+  std::vector<scoped_ptr<SBChunkData>> chunks;
   chunks.push_back(AddChunkFullHash(1, kFullHash1_1));
   chunks.push_back(AddChunkFullHash(2, kFullHash1_2));
 
   std::vector<SBListChunkRanges> lists;
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  database_->InsertChunks(kMalwareList, chunks.get());
+  database_->InsertChunks(kMalwareList, chunks);
   database_->UpdateFinished(true);
 
   {
@@ -1972,7 +1972,7 @@
   chunks.push_back(SubChunkFullHash(11, kFullHash1_1, 1));
 
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  database_->InsertChunks(kMalwareList, chunks.get());
+  database_->InsertChunks(kMalwareList, chunks);
   database_->UpdateFinished(true);
 
   // Cache should be cleared after updating.
@@ -2010,7 +2010,7 @@
   chunks.push_back(SubChunkFullHash(12, kFullHash1_2, 2));
 
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  database_->InsertChunks(kMalwareList, chunks.get());
+  database_->InsertChunks(kMalwareList, chunks);
   database_->UpdateFinished(true);
 
   // Cache should be cleared after updating.
@@ -2037,12 +2037,12 @@
   const SBFullHash kFullHash1_2 =
       SBFullHashForPrefixAndSuffix(kPrefix1, "\x02");
 
-  ScopedVector<SBChunkData> chunks;
+  std::vector<scoped_ptr<SBChunkData>> chunks;
   chunks.push_back(AddChunkFullHash(1, kFullHash1_1));
 
   std::vector<SBListChunkRanges> lists;
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  database_->InsertChunks(kMalwareList, chunks.get());
+  database_->InsertChunks(kMalwareList, chunks);
   database_->UpdateFinished(true);
 
   {
@@ -2059,7 +2059,7 @@
   chunks.push_back(AddChunkPrefix(2, kPrefix1));
 
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  database_->InsertChunks(kMalwareList, chunks.get());
+  database_->InsertChunks(kMalwareList, chunks);
   database_->UpdateFinished(true);
 
   {
@@ -2079,7 +2079,7 @@
   chunks.push_back(SubChunkFullHash(11, kFullHash1_1, 1));
 
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  database_->InsertChunks(kMalwareList, chunks.get());
+  database_->InsertChunks(kMalwareList, chunks);
   database_->UpdateFinished(true);
 
   {
@@ -2099,7 +2099,7 @@
   std::vector<SBListChunkRanges> lists;
   ASSERT_TRUE(database_->UpdateStarted(&lists));
 
-  ScopedVector<SBChunkData> chunks;
+  std::vector<scoped_ptr<SBChunkData>> chunks;
 
   // IPv4 prefix match for ::ffff:192.168.1.0/120.
   chunks.push_back(AddChunkHashedIpValue(1, "::ffff:192.168.1.0", 120));
@@ -2119,7 +2119,7 @@
   // IPv4 prefix match for ::ffff:192.1.128.0/113.
   chunks.push_back(AddChunkHashedIpValue(6, "::ffff:192.1.128.0", 113));
 
-  database_->InsertChunks(kIPBlacklist, chunks.get());
+  database_->InsertChunks(kIPBlacklist, chunks);
   database_->UpdateFinished(true);
 
   EXPECT_FALSE(database_->ContainsMalwareIP("192.168.0.255"));
@@ -2167,17 +2167,17 @@
 
   // Add a host-level hit.
   {
-    ScopedVector<SBChunkData> chunks;
+    std::vector<scoped_ptr<SBChunkData>> chunks;
     chunks.push_back(AddChunkPrefixValue(1, "www.evil.com/"));
-    database_->InsertChunks(kMalwareList, chunks.get());
+    database_->InsertChunks(kMalwareList, chunks);
   }
 
   // Add a specific fullhash.
   static const char kWhateverMalware[] = "www.whatever.com/malware.html";
   {
-    ScopedVector<SBChunkData> chunks;
+    std::vector<scoped_ptr<SBChunkData>> chunks;
     chunks.push_back(AddChunkFullHashValue(2, kWhateverMalware));
-    database_->InsertChunks(kMalwareList, chunks.get());
+    database_->InsertChunks(kMalwareList, chunks);
   }
 
   // Add a fullhash which has a prefix collision for a known url.
@@ -2187,9 +2187,9 @@
   ASSERT_EQ(SBPrefixForString(kExampleFine),
             SBPrefixForString(kExampleCollision));
   {
-    ScopedVector<SBChunkData> chunks;
+    std::vector<scoped_ptr<SBChunkData>> chunks;
     chunks.push_back(AddChunkFullHashValue(3, kExampleCollision));
-    database_->InsertChunks(kMalwareList, chunks.get());
+    database_->InsertChunks(kMalwareList, chunks);
   }
 
   database_->UpdateFinished(true);
diff --git a/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc b/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc
index 33c75ac..f0c507b 100644
--- a/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc
@@ -178,8 +178,9 @@
     ADD_FAILURE() << "Not implemented.";
     return false;
   }
-  void InsertChunks(const std::string& list_name,
-                    const std::vector<SBChunkData*>& chunks) override {
+  void InsertChunks(
+      const std::string& list_name,
+      const std::vector<scoped_ptr<SBChunkData>>& chunks) override {
     ADD_FAILURE() << "Not implemented.";
   }
   void DeleteChunks(const std::vector<SBChunkDelete>& chunk_deletes) override {
diff --git a/chrome/browser/safe_browsing/safe_browsing_util.cc b/chrome/browser/safe_browsing/safe_browsing_util.cc
index 1d4ec5f..167e103 100644
--- a/chrome/browser/safe_browsing/safe_browsing_util.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_util.cc
@@ -22,8 +22,8 @@
 SBChunkData::SBChunkData() {
 }
 
-SBChunkData::SBChunkData(ChunkData* raw_data)
-    : chunk_data_(raw_data) {
+SBChunkData::SBChunkData(scoped_ptr<ChunkData> data)
+    : chunk_data_(data.Pass()) {
   DCHECK(chunk_data_.get());
 }
 
diff --git a/chrome/browser/safe_browsing/safe_browsing_util.h b/chrome/browser/safe_browsing/safe_browsing_util.h
index c4d1812..94972a2d 100644
--- a/chrome/browser/safe_browsing/safe_browsing_util.h
+++ b/chrome/browser/safe_browsing/safe_browsing_util.h
@@ -37,7 +37,7 @@
   // Create with manufactured data, for testing only.
   // TODO(shess): Right now the test code calling this is in an anonymous
   // namespace.  Figure out how to shift this into private:.
-  explicit SBChunkData(ChunkData* chunk_data);
+  explicit SBChunkData(scoped_ptr<ChunkData> data);
 
   // Read serialized ChunkData, returning true if the parse suceeded.
   bool ParseFrom(const unsigned char* data, size_t length);
diff --git a/chrome/browser/supervised_user/supervised_user_whitelist_service.cc b/chrome/browser/supervised_user/supervised_user_whitelist_service.cc
index 7fdc0c1..458e573 100644
--- a/chrome/browser/supervised_user/supervised_user_whitelist_service.cc
+++ b/chrome/browser/supervised_user/supervised_user_whitelist_service.cc
@@ -67,13 +67,31 @@
                  weak_ptr_factory_.GetWeakPtr()));
 
   // Register whitelists specified on the command line.
+  for (const auto& whitelist : GetWhitelistsFromCommandLine())
+    RegisterWhitelist(whitelist.first, whitelist.second, FROM_COMMAND_LINE);
+}
+
+void SupervisedUserWhitelistService::AddSiteListsChangedCallback(
+    const SiteListsChangedCallback& callback) {
+  site_lists_changed_callbacks_.push_back(callback);
+
+  std::vector<scoped_refptr<SupervisedUserSiteList>> whitelists;
+  GetLoadedWhitelists(&whitelists);
+  callback.Run(whitelists);
+}
+
+// static
+std::map<std::string, std::string>
+SupervisedUserWhitelistService::GetWhitelistsFromCommandLine() {
+  std::map<std::string, std::string> whitelists;
   const base::CommandLine* command_line =
       base::CommandLine::ForCurrentProcess();
   std::string command_line_whitelists = command_line->GetSwitchValueASCII(
       switches::kInstallSupervisedUserWhitelists);
-  for (const base::StringPiece& whitelist : base::SplitStringPiece(
-           command_line_whitelists, ",",
-           base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) {
+  std::vector<base::StringPiece> string_pieces =
+      base::SplitStringPiece(command_line_whitelists, ",",
+                             base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
+  for (const base::StringPiece& whitelist : string_pieces) {
     std::string id;
     std::string name;
     size_t separator = whitelist.find(':');
@@ -84,17 +102,11 @@
       whitelist.CopyToString(&id);
     }
 
-    RegisterWhitelist(id, name, FROM_COMMAND_LINE);
+    const bool result = whitelists.insert(std::make_pair(id, name)).second;
+    DCHECK(result);
   }
-}
 
-void SupervisedUserWhitelistService::AddSiteListsChangedCallback(
-    const SiteListsChangedCallback& callback) {
-  site_lists_changed_callbacks_.push_back(callback);
-
-  std::vector<scoped_refptr<SupervisedUserSiteList>> whitelists;
-  GetLoadedWhitelists(&whitelists);
-  callback.Run(whitelists);
+  return whitelists;
 }
 
 void SupervisedUserWhitelistService::LoadWhitelistForTesting(
diff --git a/chrome/browser/supervised_user/supervised_user_whitelist_service.h b/chrome/browser/supervised_user/supervised_user_whitelist_service.h
index e31f344d..cf80bfb1 100644
--- a/chrome/browser/supervised_user/supervised_user_whitelist_service.h
+++ b/chrome/browser/supervised_user/supervised_user_whitelist_service.h
@@ -57,6 +57,10 @@
   // site lists.
   void AddSiteListsChangedCallback(const SiteListsChangedCallback& callback);
 
+  // Returns a map (from CRX ID to name) of whitelists to be installed,
+  // specified on the command line.
+  static std::map<std::string, std::string> GetWhitelistsFromCommandLine();
+
   // Loads an already existing whitelist on disk (i.e. without downloading it as
   // a component).
   void LoadWhitelistForTesting(const std::string& id,
diff --git a/chrome/browser/themes/theme_properties.cc b/chrome/browser/themes/theme_properties.cc
index 406aa36..2ea97c9 100644
--- a/chrome/browser/themes/theme_properties.cc
+++ b/chrome/browser/themes/theme_properties.cc
@@ -10,6 +10,7 @@
 #include "chrome/browser/themes/browser_theme_pack.h"
 #include "grit/theme_resources.h"
 #include "ui/base/resource/material_design/material_design_controller.h"
+#include "ui/gfx/color_palette.h"
 #include "ui/resources/grit/ui_resources.h"
 
 namespace {
@@ -313,7 +314,6 @@
       return kDefaultColorToolbarStrokeInactive;
 #endif
     default:
-      // Return a debugging red color.
-      return SK_ColorRED;
+      return gfx::kPlaceholderColor;
   }
 }
diff --git a/chrome/browser/themes/theme_properties.h b/chrome/browser/themes/theme_properties.h
index 33755a4..9171723 100644
--- a/chrome/browser/themes/theme_properties.h
+++ b/chrome/browser/themes/theme_properties.h
@@ -146,7 +146,7 @@
   static color_utils::HSL GetDefaultTint(int id);
 
   // Returns the default color for the given color |id| COLOR_* enum value.
-  // Returns SK_ColorRED if |id| is invalid.
+  // Returns gfx::kPlaceholderColor if |id| is invalid.
   static SkColor GetDefaultColor(int id);
 
  private:
diff --git a/chrome/browser/ui/ash/chrome_shell_delegate_chromeos.cc b/chrome/browser/ui/ash/chrome_shell_delegate_chromeos.cc
index 80b6b095..c330a95 100644
--- a/chrome/browser/ui/ash/chrome_shell_delegate_chromeos.cc
+++ b/chrome/browser/ui/ash/chrome_shell_delegate_chromeos.cc
@@ -18,6 +18,7 @@
 #include "chrome/browser/chromeos/background/ash_user_wallpaper_delegate.h"
 #include "chrome/browser/chromeos/display/display_configuration_observer.h"
 #include "chrome/browser/chromeos/display/display_preferences.h"
+#include "chrome/browser/chromeos/policy/display_rotation_default_handler.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
@@ -224,6 +225,8 @@
 
 void ChromeShellDelegate::PreInit() {
   chromeos::LoadDisplayPreferences(IsFirstRunAfterBoot());
+  // Object owns itself, and deletes itself when Observer::OnShutdown is called:
+  new policy::DisplayRotationDefaultHandler();
   // Set the observer now so that we can save the initial state
   // in Shell::Init.
   display_configuration_observer_.reset(
diff --git a/chrome/browser/ui/browser_window.h b/chrome/browser/ui/browser_window.h
index 7f4d216..b41962f 100644
--- a/chrome/browser/ui/browser_window.h
+++ b/chrome/browser/ui/browser_window.h
@@ -268,11 +268,6 @@
       translate::TranslateErrors::Type error_type,
       bool is_user_gesture) = 0;
 
-  // Shows the profile reset bubble on the platforms that support it.
-  virtual bool IsProfileResetBubbleSupported() const = 0;
-  virtual GlobalErrorBubbleViewBase* ShowProfileResetBubble(
-      const base::WeakPtr<ProfileResetGlobalError>& global_error) = 0;
-
 #if defined(ENABLE_ONE_CLICK_SIGNIN)
   enum OneClickSigninBubbleType {
     ONE_CLICK_SIGNIN_BUBBLE_TYPE_BUBBLE,
diff --git a/chrome/browser/ui/cocoa/browser_window_cocoa.h b/chrome/browser/ui/cocoa/browser_window_cocoa.h
index c58e1be..43f633c4 100644
--- a/chrome/browser/ui/cocoa/browser_window_cocoa.h
+++ b/chrome/browser/ui/cocoa/browser_window_cocoa.h
@@ -124,9 +124,6 @@
                            translate::TranslateStep step,
                            translate::TranslateErrors::Type error_type,
                            bool is_user_gesture) override;
-  bool IsProfileResetBubbleSupported() const override;
-  GlobalErrorBubbleViewBase* ShowProfileResetBubble(
-      const base::WeakPtr<ProfileResetGlobalError>& global_error) override;
 #if defined(ENABLE_ONE_CLICK_SIGNIN)
   void ShowOneClickSigninBubble(
       OneClickSigninBubbleType type,
diff --git a/chrome/browser/ui/cocoa/browser_window_cocoa.mm b/chrome/browser/ui/cocoa/browser_window_cocoa.mm
index d98c565..0c703069 100644
--- a/chrome/browser/ui/cocoa/browser_window_cocoa.mm
+++ b/chrome/browser/ui/cocoa/browser_window_cocoa.mm
@@ -661,16 +661,6 @@
                                        errorType:error_type];
 }
 
-bool BrowserWindowCocoa::IsProfileResetBubbleSupported() const {
-  return false;
-}
-
-GlobalErrorBubbleViewBase* BrowserWindowCocoa::ShowProfileResetBubble(
-    const base::WeakPtr<ProfileResetGlobalError>& global_error) {
-  NOTREACHED();
-  return nullptr;
-}
-
 #if defined(ENABLE_ONE_CLICK_SIGNIN)
 void BrowserWindowCocoa::ShowOneClickSigninBubble(
     OneClickSigninBubbleType type,
diff --git a/chrome/browser/ui/cocoa/passwords/passwords_list_view_controller_unittest.mm b/chrome/browser/ui/cocoa/passwords/passwords_list_view_controller_unittest.mm
index 7f8f3bd..adf8ea8 100644
--- a/chrome/browser/ui/cocoa/passwords/passwords_list_view_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/passwords/passwords_list_view_controller_unittest.mm
@@ -37,7 +37,7 @@
     ManagePasswordsControllerTest::SetUp();
     PasswordStoreFactory::GetInstance()->SetTestingFactory(
         profile(),
-        password_manager::BuildPasswordStoreService<
+        password_manager::BuildPasswordStore<
             content::BrowserContext, password_manager::MockPasswordStore>);
   }
 
diff --git a/chrome/browser/ui/extensions/extension_action_view_controller.cc b/chrome/browser/ui/extensions/extension_action_view_controller.cc
index 22decd3..84ed17a 100644
--- a/chrome/browser/ui/extensions/extension_action_view_controller.cc
+++ b/chrome/browser/ui/extensions/extension_action_view_controller.cc
@@ -27,6 +27,7 @@
 #include "extensions/common/extension.h"
 #include "extensions/common/feature_switch.h"
 #include "extensions/common/manifest_constants.h"
+#include "ui/base/resource/material_design/material_design_controller.h"
 #include "ui/gfx/image/image_skia.h"
 #include "ui/gfx/image/image_skia_operations.h"
 
@@ -364,7 +365,18 @@
   int tab_id = SessionTabHelper::IdForTab(web_contents);
   scoped_ptr<IconWithBadgeImageSource> image_source(
       new IconWithBadgeImageSource(size));
-  image_source->SetIcon(icon_factory_.GetIcon(tab_id));
+
+  gfx::Image icon(icon_factory_.GetIcon(tab_id));
+  if (ui::MaterialDesignController::IsModeMaterial()) {
+    // TODO(tdanderson): Use a 16x16 icon if it exists instead of resizing.
+    icon = gfx::Image(gfx::ImageSkiaOperations::CreateResizedImage(
+        *icon.ToImageSkia(),
+        skia::ImageOperations::RESIZE_BEST,
+        gfx::Size(extension_misc::EXTENSION_ICON_BITTY,
+                  extension_misc::EXTENSION_ICON_BITTY)));
+  }
+  image_source->SetIcon(icon);
+
   scoped_ptr<IconWithBadgeImageSource::Badge> badge;
   std::string badge_text = extension_action_->GetBadgeText(tab_id);
   if (!badge_text.empty()) {
diff --git a/chrome/browser/ui/login/login_prompt_browsertest.cc b/chrome/browser/ui/login/login_prompt_browsertest.cc
index b28c248..c4a7738c 100644
--- a/chrome/browser/ui/login/login_prompt_browsertest.cc
+++ b/chrome/browser/ui/login/login_prompt_browsertest.cc
@@ -1423,22 +1423,12 @@
   }
 }
 
-// Fails on non-aura because of crbug.com/555804.
-// TODO(meacer): Enable for all when that bug is fixed.
-#if defined(USE_AURA)
-#define MAYBE_ShouldNotProceedExistingInterstitial \
-  ShouldNotProceedExistingInterstitial
-#else
-#define MAYBE_ShouldNotProceedExistingInterstitial \
-  DISABLED_MAYBE_ShouldNotProceedExistingInterstitial
-#endif
-
 // Test that the login interstitial isn't proceeding itself or any other
 // interstitial. If this test becomes flaky, it's likely that the logic that
 // prevents the tested scenario from happening got broken, rather than the test
 // itself.
 IN_PROC_BROWSER_TEST_F(LoginPromptBrowserTest,
-                       MAYBE_ShouldNotProceedExistingInterstitial) {
+                       ShouldNotProceedExistingInterstitial) {
   net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
   https_server.SetSSLConfig(net::EmbeddedTestServer::CERT_EXPIRED);
   ASSERT_TRUE(https_server.Start());
diff --git a/chrome/browser/ui/passwords/password_manager_presenter_unittest.cc b/chrome/browser/ui/passwords/password_manager_presenter_unittest.cc
index a2ebe32..ccb7e01 100644
--- a/chrome/browser/ui/passwords/password_manager_presenter_unittest.cc
+++ b/chrome/browser/ui/passwords/password_manager_presenter_unittest.cc
@@ -59,7 +59,7 @@
   void SetUp() override {
     PasswordStoreFactory::GetInstance()->SetTestingFactory(
         &profile_,
-        password_manager::BuildPasswordStoreService<
+        password_manager::BuildPasswordStore<
             content::BrowserContext, password_manager::MockPasswordStore>);
     mock_controller_.reset(new MockPasswordUIView(&profile_));
   }
diff --git a/chrome/browser/ui/views/app_list/app_list_dialog_container.cc b/chrome/browser/ui/views/app_list/app_list_dialog_container.cc
index 4b23b2e0..55fbbc32 100644
--- a/chrome/browser/ui/views/app_list/app_list_dialog_container.cc
+++ b/chrome/browser/ui/views/app_list/app_list_dialog_container.cc
@@ -13,6 +13,7 @@
 #include "ui/events/event_constants.h"
 #include "ui/events/keycodes/keyboard_codes.h"
 #include "ui/gfx/canvas.h"
+#include "ui/gfx/color_palette.h"
 #include "ui/resources/grit/ui_resources.h"
 #include "ui/views/background.h"
 #include "ui/views/border.h"
@@ -214,7 +215,7 @@
       views::Widget* widget) override {
     FullSizeBubbleFrameView* frame = new FullSizeBubbleFrameView();
     scoped_ptr<views::BubbleBorder> border(new views::BubbleBorder(
-        views::BubbleBorder::FLOAT, kShadowType, SK_ColorRED));
+        views::BubbleBorder::FLOAT, kShadowType, gfx::kPlaceholderColor));
     border->set_use_theme_background_color(true);
     frame->SetBubbleBorder(border.Pass());
     return frame;
diff --git a/chrome/browser/ui/views/download/download_item_view_md.cc b/chrome/browser/ui/views/download/download_item_view_md.cc
index ecfd25f..8b11b4a 100644
--- a/chrome/browser/ui/views/download/download_item_view_md.cc
+++ b/chrome/browser/ui/views/download/download_item_view_md.cc
@@ -220,7 +220,7 @@
 SkColor DownloadItemViewMd::GetTextColorForThemeProvider(
     ui::ThemeProvider* theme) {
   return theme ? theme->GetColor(ThemeProperties::COLOR_BOOKMARK_TEXT)
-               : SK_ColorRED;
+               : gfx::kPlaceholderColor;
 }
 
 void DownloadItemViewMd::OnExtractIconComplete(gfx::Image* icon_bitmap) {
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc
index 810d9f0..1271b2f 100644
--- a/chrome/browser/ui/views/frame/browser_view.cc
+++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -80,7 +80,6 @@
 #include "chrome/browser/ui/views/omnibox/omnibox_view_views.h"
 #include "chrome/browser/ui/views/profiles/avatar_menu_button.h"
 #include "chrome/browser/ui/views/profiles/profile_chooser_view.h"
-#include "chrome/browser/ui/views/profiles/profile_reset_bubble_view.h"
 #include "chrome/browser/ui/views/session_crashed_bubble_view.h"
 #include "chrome/browser/ui/views/settings_api_bubble_helper_views.h"
 #include "chrome/browser/ui/views/status_bubble_views.h"
@@ -1330,15 +1329,6 @@
                                   : TranslateBubbleView::AUTOMATIC);
 }
 
-bool BrowserView::IsProfileResetBubbleSupported() const {
-  return true;
-}
-
-GlobalErrorBubbleViewBase* BrowserView::ShowProfileResetBubble(
-    const base::WeakPtr<ProfileResetGlobalError>& global_error) {
-  return ProfileResetBubbleView::ShowBubble(global_error, browser_.get());
-}
-
 #if defined(ENABLE_ONE_CLICK_SIGNIN)
 void BrowserView::ShowOneClickSigninBubble(
     OneClickSigninBubbleType type,
diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h
index 1f0e6c0..5b1490c 100644
--- a/chrome/browser/ui/views/frame/browser_view.h
+++ b/chrome/browser/ui/views/frame/browser_view.h
@@ -326,9 +326,6 @@
                            translate::TranslateStep step,
                            translate::TranslateErrors::Type error_type,
                            bool is_user_gesture) override;
-  bool IsProfileResetBubbleSupported() const override;
-  GlobalErrorBubbleViewBase* ShowProfileResetBubble(
-      const base::WeakPtr<ProfileResetGlobalError>& global_error) override;
 #if defined(ENABLE_ONE_CLICK_SIGNIN)
   void ShowOneClickSigninBubble(
       OneClickSigninBubbleType type,
diff --git a/chrome/browser/ui/views/location_bar/keyword_hint_view.cc b/chrome/browser/ui/views/location_bar/keyword_hint_view.cc
index 02d1ff61..80f4d17 100644
--- a/chrome/browser/ui/views/location_bar/keyword_hint_view.cc
+++ b/chrome/browser/ui/views/location_bar/keyword_hint_view.cc
@@ -21,6 +21,7 @@
 #include "ui/base/resource/material_design/material_design_controller.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/gfx/canvas.h"
+#include "ui/gfx/color_palette.h"
 #include "ui/strings/grit/ui_strings.h"
 #include "ui/views/controls/image_view.h"
 #include "ui/views/controls/label.h"
@@ -48,7 +49,11 @@
 TabKeyBubbleView::TabKeyBubbleView(const gfx::FontList& font_list,
                                    SkColor text_color,
                                    SkColor background_color)
-    : IconLabelBubbleView(0, font_list, SK_ColorRED, background_color, false),
+    : IconLabelBubbleView(0,
+                          font_list,
+                          gfx::kPlaceholderColor,
+                          background_color,
+                          false),
       text_color_(text_color) {
   SetLabel(l10n_util::GetStringUTF16(IDS_APP_TAB_KEY));
 }
diff --git a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
index 0ab0325d..3154225 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
@@ -257,7 +257,7 @@
   }
 
   NOTREACHED();
-  return SK_ColorRED;
+  return gfx::kPlaceholderColor;
 }
 
 void OmniboxResultView::SetMatch(const AutocompleteMatch& match) {
diff --git a/chrome/browser/ui/views/profiles/profile_reset_bubble_view.cc b/chrome/browser/ui/views/profiles/profile_reset_bubble_view.cc
deleted file mode 100644
index 8aaed74..0000000
--- a/chrome/browser/ui/views/profiles/profile_reset_bubble_view.cc
+++ /dev/null
@@ -1,438 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/ui/views/profiles/profile_reset_bubble_view.h"
-
-#include "chrome/app/chrome_command_ids.h"
-#include "chrome/browser/profile_resetter/profile_reset_global_error.h"
-#include "chrome/browser/profile_resetter/resettable_settings_snapshot.h"
-#include "chrome/browser/ui/global_error/global_error_service.h"
-#include "chrome/browser/ui/global_error/global_error_service_factory.h"
-#include "chrome/browser/ui/views/frame/browser_view.h"
-#include "chrome/browser/ui/views/toolbar/app_menu_button.h"
-#include "chrome/browser/ui/views/toolbar/toolbar_view.h"
-#include "chrome/common/url_constants.h"
-#include "components/google/core/browser/google_util.h"
-#include "content/public/browser/page_navigator.h"
-#include "content/public/browser/user_metrics.h"
-#include "grit/chromium_strings.h"
-#include "grit/components_strings.h"
-#include "grit/generated_resources.h"
-#include "grit/theme_resources.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "ui/base/resource/resource_bundle.h"
-#include "ui/gfx/image/image_skia_operations.h"
-#include "ui/views/background.h"
-#include "ui/views/controls/button/checkbox.h"
-#include "ui/views/controls/button/image_button.h"
-#include "ui/views/controls/button/label_button.h"
-#include "ui/views/controls/label.h"
-#include "ui/views/controls/link.h"
-#include "ui/views/controls/scroll_view.h"
-#include "ui/views/controls/separator.h"
-#include "ui/views/layout/grid_layout.h"
-#include "ui/views/layout/layout_constants.h"
-
-using views::GridLayout;
-
-namespace {
-
-// Fixed width of the column holding the description label of the bubble.
-const int kWidthOfDescriptionText = 370;
-
-// Margins width for the top rows to compensate for the bottom panel for which
-// we don't want any margin.
-const int kMarginWidth = 12;
-const int kMarginHeight = kMarginWidth;
-
-// Width of a colum in the FeedbackView.
-const int kFeedbackViewColumnWidth = kWidthOfDescriptionText / 2 + kMarginWidth;
-
-// Width of the column used to disaplay the help button.
-const int kHelpButtonColumnWidth = 30;
-
-// Width of the reporting checkbox column.
-const int kReportingCheckboxColumnWidth =
-    kWidthOfDescriptionText + 2 * kMarginWidth;
-
-// Full width including all columns.
-const int kAllColumnsWidth =
-    kReportingCheckboxColumnWidth + kHelpButtonColumnWidth;
-
-// Maximum height of the scrollable feedback view.
-const int kMaxFeedbackViewHeight = 450;
-
-// The vertical padding between two values in the feedback view.
-const int kInterFeedbackValuePadding = 4;
-
-// We subtract 2 to account for the natural button padding, and
-// to bring the separation visually in line with the row separation
-// height.
-const int kButtonPadding = views::kRelatedButtonHSpacing - 2;
-
-// The color of the background of the sub panel to report current settings.
-const SkColor kLightGrayBackgroundColor = 0xFFF5F5F5;
-
-// This view is used to contain the scrollable contents that are shown the user
-// to expose what feedback will be sent back to Google.
-class FeedbackView : public views::View {
- public:
-  FeedbackView() {}
-
-  // Setup the layout manager of the Feedback view using the content of the
-  // |feedback| ListValue which contains a list of key/value pairs stored in
-  // DictionaryValues. The key is to be displayed right aligned on the left, and
-  // the value as a left aligned multiline text on the right.
-  void SetupLayoutManager(const base::ListValue& feedback) {
-    RemoveAllChildViews(true);
-    set_background(views::Background::CreateSolidBackground(
-        kLightGrayBackgroundColor));
-
-    GridLayout* layout = new GridLayout(this);
-    SetLayoutManager(layout);
-
-    // We only need a single column set for left/right text and middle margin.
-    views::ColumnSet* cs = layout->AddColumnSet(0);
-    cs->AddColumn(GridLayout::FILL, GridLayout::LEADING, 1,
-                  GridLayout::FIXED, kFeedbackViewColumnWidth, 0);
-    cs->AddPaddingColumn(0, kMarginWidth);
-    cs->AddColumn(GridLayout::FILL, GridLayout::FILL, 1,
-                  GridLayout::FIXED, kFeedbackViewColumnWidth, 0);
-    for (size_t i = 0; i < feedback.GetSize(); ++i) {
-      const base::DictionaryValue* dictionary = NULL;
-      if (!feedback.GetDictionary(i, &dictionary) || !dictionary)
-        continue;
-
-      base::string16 key;
-      if (!dictionary->GetString("key", &key))
-        continue;
-
-      base::string16 value;
-      if (!dictionary->GetString("value", &value))
-        continue;
-
-      // The key is shown on the left, multi-line (required to allow wrapping in
-      // case the key name does not fit), and right-aligned.
-      views::Label* left_text_label = new views::Label(key);
-      left_text_label->SetMultiLine(true);
-      left_text_label->SetEnabledColor(SK_ColorGRAY);
-      left_text_label->SetHorizontalAlignment(gfx::ALIGN_RIGHT);
-
-      // The value is shown on the right, multi-line, left-aligned.
-      views::Label* right_text_label = new views::Label(value);
-      right_text_label->SetMultiLine(true);
-      right_text_label->SetEnabledColor(SK_ColorDKGRAY);
-      right_text_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
-
-      layout->StartRow(0, 0);
-      layout->AddView(left_text_label);
-      layout->AddView(right_text_label);
-      layout->AddPaddingRow(0, kInterFeedbackValuePadding);
-    }
-
-    // We need to set our size to our preferred size because our parent is a
-    // scroll view and doesn't know which size to set us to. Also since our
-    // parent scrolls, we are not bound to its size. So our size is based on the
-    // size computed by the our layout manager, which is what
-    // SizeToPreferredSize() does.
-    SizeToPreferredSize();
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(FeedbackView);
-};
-
-}  // namespace
-
-// ProfileResetBubbleView ---------------------------------------------------
-
-// static
-ProfileResetBubbleView* ProfileResetBubbleView::ShowBubble(
-    const base::WeakPtr<ProfileResetGlobalError>& global_error,
-    Browser* browser) {
-  views::View* anchor_view = BrowserView::GetBrowserViewForBrowser(browser)
-                                 ->toolbar()
-                                 ->app_menu_button();
-  ProfileResetBubbleView* reset_bubble = new ProfileResetBubbleView(
-      global_error, anchor_view, browser, browser->profile());
-  views::BubbleDelegateView::CreateBubble(reset_bubble)->Show();
-  content::RecordAction(base::UserMetricsAction("SettingsResetBubble.Show"));
-  return reset_bubble;
-}
-
-ProfileResetBubbleView::~ProfileResetBubbleView() {}
-
-views::View* ProfileResetBubbleView::GetInitiallyFocusedView() {
-  return controls_.reset_button;
-}
-
-void ProfileResetBubbleView::WindowClosing() {
-  if (global_error_)
-    global_error_->OnBubbleViewDidClose();
-}
-
-ProfileResetBubbleView::ProfileResetBubbleView(
-    const base::WeakPtr<ProfileResetGlobalError>& global_error,
-    views::View* anchor_view,
-    content::PageNavigator* navigator,
-    Profile* profile)
-    : BubbleDelegateView(anchor_view, views::BubbleBorder::TOP_RIGHT),
-      navigator_(navigator),
-      profile_(profile),
-      global_error_(global_error),
-      resetting_(false),
-      chose_to_reset_(false),
-      show_help_pane_(false),
-      weak_factory_(this) {
-}
-
-void ProfileResetBubbleView::ResetAllChildren() {
-  controls_.Reset();
-  SetLayoutManager(NULL);
-  RemoveAllChildViews(true);
-}
-
-void ProfileResetBubbleView::Init() {
-  set_margins(gfx::Insets(kMarginHeight, 0, 0, 0));
-  // Start requesting the feedback data.
-  snapshot_.reset(new ResettableSettingsSnapshot(profile_));
-  snapshot_->RequestShortcuts(
-      base::Bind(&ProfileResetBubbleView::UpdateFeedbackDetails,
-                 weak_factory_.GetWeakPtr()));
-  SetupLayoutManager(true);
-}
-
-void ProfileResetBubbleView::SetupLayoutManager(bool report_checked) {
-  ResetAllChildren();
-
-  base::string16 product_name(
-      l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_NAME));
-  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
-
-  // Bubble title label.
-  views::Label* title_label = new views::Label(
-      l10n_util::GetStringFUTF16(IDS_RESET_BUBBLE_TITLE, product_name),
-      rb.GetFontList(ui::ResourceBundle::BoldFont));
-  title_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
-
-  // Description text label.
-  views::Label* text_label = new views::Label(
-      l10n_util::GetStringFUTF16(IDS_RESET_BUBBLE_TEXT, product_name));
-  text_label->SetMultiLine(true);
-  text_label->SetLineHeight(20);
-  text_label->SetEnabledColor(SK_ColorDKGRAY);
-  text_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
-
-  // Learn more link.
-  views::Link* learn_more_link = new views::Link(
-      l10n_util::GetStringUTF16(IDS_LEARN_MORE));
-  learn_more_link->SetHorizontalAlignment(gfx::ALIGN_LEFT);
-  learn_more_link->set_listener(this);
-  learn_more_link->SetUnderline(false);
-
-  // Reset button's name is based on |resetting_| state.
-  int reset_button_string_id = IDS_RESET_PROFILE_SETTINGS_COMMIT_BUTTON;
-  if (resetting_)
-    reset_button_string_id = IDS_RESETTING;
-  controls_.reset_button = new views::LabelButton(
-      this, l10n_util::GetStringUTF16(reset_button_string_id));
-  controls_.reset_button->SetStyle(views::Button::STYLE_BUTTON);
-  controls_.reset_button->SetIsDefault(true);
-  controls_.reset_button->SetFontList(
-      rb.GetFontList(ui::ResourceBundle::BoldFont));
-  controls_.reset_button->SetEnabled(!resetting_);
-  // For the Resetting... text to fit.
-  gfx::Size reset_button_size = controls_.reset_button->GetPreferredSize();
-  reset_button_size.set_width(100);
-  controls_.reset_button->SetMinSize(reset_button_size);
-
-  // No thanks button.
-  controls_.no_thanks_button = new views::LabelButton(
-      this, l10n_util::GetStringUTF16(IDS_NO_THANKS));
-  controls_.no_thanks_button->SetStyle(views::Button::STYLE_BUTTON);
-  controls_.no_thanks_button->SetEnabled(!resetting_);
-
-  // Checkbox for reporting settings or not.
-  controls_.report_settings_checkbox = new views::Checkbox(
-      l10n_util::GetStringUTF16(IDS_REPORT_BUBBLE_TEXT));
-  controls_.report_settings_checkbox->SetTextColor(
-      views::Button::STATE_NORMAL, SK_ColorGRAY);
-  controls_.report_settings_checkbox->SetChecked(report_checked);
-  controls_.report_settings_checkbox->SetTextMultiLine(true);
-  controls_.report_settings_checkbox->set_background(
-      views::Background::CreateSolidBackground(kLightGrayBackgroundColor));
-  // Have a smaller margin on the right, to have the |controls_.help_button|
-  // closer to the edge.
-  controls_.report_settings_checkbox->SetBorder(
-      views::Border::CreateSolidSidedBorder(kMarginWidth,
-                                            kMarginWidth,
-                                            kMarginWidth,
-                                            kMarginWidth / 2,
-                                            kLightGrayBackgroundColor));
-
-  // Help button to toggle the bottom panel on or off.
-  controls_.help_button = new views::ImageButton(this);
-  const gfx::ImageSkia* help_image = rb.GetImageSkiaNamed(IDR_QUESTION_MARK);
-  color_utils::HSL hsl_shift = { -1, 0, 0.8 };
-  brighter_help_image_ = gfx::ImageSkiaOperations::CreateHSLShiftedImage(
-      *help_image, hsl_shift);
-  controls_.help_button->SetImage(
-      views::Button::STATE_NORMAL, &brighter_help_image_);
-  controls_.help_button->SetImage(views::Button::STATE_HOVERED, help_image);
-  controls_.help_button->SetImage(views::Button::STATE_PRESSED, help_image);
-  controls_.help_button->set_background(
-      views::Background::CreateSolidBackground(kLightGrayBackgroundColor));
-  controls_.help_button->SetImageAlignment(views::ImageButton::ALIGN_CENTER,
-                                  views::ImageButton::ALIGN_MIDDLE);
-
-  GridLayout* layout = new GridLayout(this);
-  SetLayoutManager(layout);
-
-  // Title row.
-  const int kTitleColumnSetId = 0;
-  views::ColumnSet* cs = layout->AddColumnSet(kTitleColumnSetId);
-  cs->AddPaddingColumn(0, kMarginWidth);
-  cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0,
-                GridLayout::USE_PREF, 0, 0);
-  cs->AddPaddingColumn(0, kMarginWidth);
-
-  // Text row.
-  const int kTextColumnSetId = 1;
-  cs = layout->AddColumnSet(kTextColumnSetId);
-  cs->AddPaddingColumn(0, kMarginWidth);
-  cs->AddColumn(GridLayout::FILL, GridLayout::FILL, 0,
-                GridLayout::FIXED, kWidthOfDescriptionText, 0);
-  cs->AddPaddingColumn(0, kMarginWidth);
-
-  // Learn more link & buttons row.
-  const int kButtonsColumnSetId = 2;
-  cs = layout->AddColumnSet(kButtonsColumnSetId);
-  cs->AddPaddingColumn(0, kMarginWidth);
-  cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0,
-                GridLayout::USE_PREF, 0, 0);
-  cs->AddPaddingColumn(1, views::kRelatedControlHorizontalSpacing);
-  cs->AddColumn(GridLayout::LEADING, GridLayout::TRAILING, 0,
-                GridLayout::USE_PREF, 0, 0);
-  cs->AddPaddingColumn(0, kButtonPadding);
-  cs->AddColumn(GridLayout::LEADING, GridLayout::TRAILING, 0,
-                GridLayout::USE_PREF, 0, 0);
-  cs->AddPaddingColumn(0, kMarginWidth);
-
-  // Separator.
-  const int kSeparatorColumnSetId = 3;
-  cs = layout->AddColumnSet(kSeparatorColumnSetId);
-  cs->AddColumn(GridLayout::FILL, GridLayout::FILL, 0,
-                GridLayout::FIXED, kAllColumnsWidth, 0);
-
-  // Reporting row.
-  const int kReportColumnSetId = 4;
-  cs = layout->AddColumnSet(kReportColumnSetId);
-  cs->AddColumn(GridLayout::FILL, GridLayout::FILL, 0,
-                GridLayout::FIXED, kReportingCheckboxColumnWidth, 0);
-  cs->AddColumn(GridLayout::FILL, GridLayout::FILL, 0,
-                GridLayout::FIXED, kHelpButtonColumnWidth, 0);
-
-  layout->StartRow(0, kTitleColumnSetId);
-  layout->AddView(title_label);
-  layout->AddPaddingRow(0, kMarginHeight);
-
-  layout->StartRow(0, kTextColumnSetId);
-  layout->AddView(text_label);
-  layout->AddPaddingRow(0, kMarginHeight);
-
-  layout->StartRow(0, kButtonsColumnSetId);
-  layout->AddView(learn_more_link);
-  layout->AddView(controls_.reset_button);
-  layout->AddView(controls_.no_thanks_button);
-  layout->AddPaddingRow(0, kMarginHeight);
-
-  layout->StartRow(0, kSeparatorColumnSetId);
-  layout->AddView(new views::Separator(views::Separator::HORIZONTAL));
-
-  layout->StartRow(0, kReportColumnSetId);
-  layout->AddView(controls_.report_settings_checkbox);
-  layout->AddView(controls_.help_button);
-
-  if (show_help_pane_ && snapshot_) {
-    // We need a single row to add the scroll view containing the feedback.
-    const int kReportDetailsColumnSetId = 5;
-    cs = layout->AddColumnSet(kReportDetailsColumnSetId);
-    cs->AddColumn(GridLayout::FILL, GridLayout::FILL, 1,
-                  GridLayout::USE_PREF, 0, 0);
-
-    FeedbackView* feedback_view = new FeedbackView();
-    scoped_ptr<base::ListValue> feedback_data =
-        GetReadableFeedbackForSnapshot(profile_, *snapshot_);
-    feedback_view->SetupLayoutManager(*feedback_data);
-
-    views::ScrollView* scroll_view = new views::ScrollView();
-    scroll_view->set_background(views::Background::CreateSolidBackground(
-        kLightGrayBackgroundColor));
-    scroll_view->SetContents(feedback_view);
-
-    layout->StartRow(1, kReportDetailsColumnSetId);
-    layout->AddView(scroll_view, 1, 1, GridLayout::FILL,
-                    GridLayout::FILL, kAllColumnsWidth,
-                    std::min(feedback_view->height() + kMarginHeight,
-                             kMaxFeedbackViewHeight));
-  }
-
-  Layout();
-  AddAccelerator(ui::Accelerator(ui::VKEY_RETURN, ui::EF_NONE));
-}
-
-void ProfileResetBubbleView::ButtonPressed(views::Button* sender,
-                                           const ui::Event& event) {
-  if (sender == controls_.reset_button) {
-    DCHECK(!resetting_);
-    content::RecordAction(
-        base::UserMetricsAction("SettingsResetBubble.Reset"));
-
-    // Remember that the user chose to reset, and that resetting is underway.
-    chose_to_reset_ = true;
-    resetting_ = true;
-
-    controls_.reset_button->SetText(l10n_util::GetStringUTF16(IDS_RESETTING));
-    controls_.reset_button->SetEnabled(false);
-    controls_.no_thanks_button->SetEnabled(false);
-    SchedulePaint();
-
-    if (global_error_) {
-      global_error_->OnBubbleViewResetButtonPressed(
-          controls_.report_settings_checkbox->checked());
-    }
-  } else if (sender == controls_.no_thanks_button) {
-    DCHECK(!resetting_);
-    content::RecordAction(
-        base::UserMetricsAction("SettingsResetBubble.NoThanks"));
-
-    if (global_error_)
-      global_error_->OnBubbleViewNoThanksButtonPressed();
-    GetWidget()->Close();
-    return;
-  } else if (sender == controls_.help_button) {
-    show_help_pane_ = !show_help_pane_;
-
-    SetupLayoutManager(controls_.report_settings_checkbox->checked());
-    SizeToContents();
-  }
-}
-
-void ProfileResetBubbleView::LinkClicked(views::Link* source, int flags) {
-  content::RecordAction(
-      base::UserMetricsAction("SettingsResetBubble.LearnMore"));
-  navigator_->OpenURL(content::OpenURLParams(
-      GURL(chrome::kResetProfileSettingsLearnMoreURL), content::Referrer(),
-      NEW_FOREGROUND_TAB, ui::PAGE_TRANSITION_LINK, false));
-}
-
-void ProfileResetBubbleView::CloseBubbleView() {
-  resetting_ = false;
-  GetWidget()->Close();
-}
-
-void ProfileResetBubbleView::UpdateFeedbackDetails() {
-  if (show_help_pane_)
-    SetupLayoutManager(controls_.report_settings_checkbox->checked());
-}
diff --git a/chrome/browser/ui/views/profiles/profile_reset_bubble_view.h b/chrome/browser/ui/views/profiles/profile_reset_bubble_view.h
deleted file mode 100644
index 771822a..0000000
--- a/chrome/browser/ui/views/profiles/profile_reset_bubble_view.h
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_UI_VIEWS_PROFILES_PROFILE_RESET_BUBBLE_VIEW_H_
-#define CHROME_BROWSER_UI_VIEWS_PROFILES_PROFILE_RESET_BUBBLE_VIEW_H_
-
-#include "base/callback.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/memory/weak_ptr.h"
-#include "base/values.h"
-#include "chrome/browser/ui/global_error/global_error_bubble_view_base.h"
-#include "ui/gfx/image/image_skia.h"
-#include "ui/views/bubble/bubble_delegate.h"
-#include "ui/views/controls/button/button.h"
-#include "ui/views/controls/link_listener.h"
-
-namespace content {
-class PageNavigator;
-}
-
-namespace views {
-class Checkbox;
-class ImageButton;
-class LabelButton;
-class Link;
-}
-
-class Browser;
-class Profile;
-class ProfileResetGlobalError;
-class ResettableSettingsSnapshot;
-
-// ProfileResetBubbleView warns the user that a settings reset might be needed.
-// It is intended to be used as the content of a bubble anchored off of the
-// Chrome toolbar.
-class ProfileResetBubbleView : public views::BubbleDelegateView,
-                               public views::ButtonListener,
-                               public views::LinkListener,
-                               public GlobalErrorBubbleViewBase {
- public:
-  static ProfileResetBubbleView* ShowBubble(
-      const base::WeakPtr<ProfileResetGlobalError>& global_error,
-      Browser* browser);
-
-  // views::BubbleDelegateView methods.
-  views::View* GetInitiallyFocusedView() override;
-  void Init() override;
-
-  // views::WidgetDelegate method.
-  void WindowClosing() override;
-
-  // GlobalErrorBubbleViewBase:
-  void CloseBubbleView() override;
-
- private:
-  ProfileResetBubbleView(
-      const base::WeakPtr<ProfileResetGlobalError>& global_error,
-      views::View* anchor_view,
-      content::PageNavigator* navigator,
-      Profile* profile);
-
-  ~ProfileResetBubbleView() override;
-
-  // Reset all child views members and remove children from view hierarchy.
-  void ResetAllChildren();
-
-  // Sets up the layout manager and set the report checkbox to the value passed
-  // in |report_checked|.
-  void SetupLayoutManager(bool report_checked);
-
-  // views::ButtonListener method.
-  void ButtonPressed(views::Button* sender, const ui::Event& event) override;
-
-  // views::LinkListener method.
-  void LinkClicked(views::Link* source, int event_flags) override;
-
-  // Sets the fully populated feedback data.
-  void UpdateFeedbackDetails();
-
-  struct Controls {
-    Controls() {
-      Reset();
-    }
-    void Reset() {
-      reset_button = NULL;
-      no_thanks_button = NULL;
-      help_button = NULL;
-      report_settings_checkbox = NULL;
-    }
-
-    // Button for the user to confirm a settings reset.
-    views::LabelButton* reset_button;
-
-    // Button for the user to refuse a settings reset.
-    views::LabelButton* no_thanks_button;
-
-    // Button for the user to get more info about reporting settings.
-    views::ImageButton* help_button;
-
-    // Checkbox for the user to choose to report the settings or not.
-    views::Checkbox* report_settings_checkbox;
-  } controls_;
-
-  // The snapshot is used to show user feedback information.
-  scoped_ptr<ResettableSettingsSnapshot> snapshot_;
-
-  // A version of the help image that is brighter.
-  gfx::ImageSkia brighter_help_image_;
-
-  // Used for opening the learn more link.
-  content::PageNavigator* navigator_;
-
-  // Used to access profile specific stuff like the global error or readable
-  // feedback.
-  Profile* profile_;
-
-  // The GlobalError this Bubble belongs to.
-  base::WeakPtr<ProfileResetGlobalError> global_error_;
-
-  // Remembers if we are currently resetting or not.
-  bool resetting_;
-
-  // Remembers if the reset button was hit before closing the bubble.
-  bool chose_to_reset_;
-
-  // Toggles when the user clicks on the |help_button_| to identify if we should
-  // show the help pane or not.
-  bool show_help_pane_;
-
-  // To cancel pending callbacks after destruction.
-  base::WeakPtrFactory<ProfileResetBubbleView> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(ProfileResetBubbleView);
-};
-
-#endif  // CHROME_BROWSER_UI_VIEWS_PROFILES_PROFILE_RESET_BUBBLE_VIEW_H_
diff --git a/chrome/browser/ui/views/toolbar/app_menu_button.cc b/chrome/browser/ui/views/toolbar/app_menu_button.cc
index fe81877..c8f79fb 100644
--- a/chrome/browser/ui/views/toolbar/app_menu_button.cc
+++ b/chrome/browser/ui/views/toolbar/app_menu_button.cc
@@ -157,7 +157,7 @@
 
 void AppMenuButton::UpdateIcon() {
   DCHECK(ui::MaterialDesignController::IsModeMaterial());
-  SkColor color = SK_ColorRED;
+  SkColor color = gfx::kPlaceholderColor;
   switch (severity_) {
     case AppMenuIconPainter::SEVERITY_NONE:
       color = GetThemeProvider()->GetColor(
diff --git a/chrome/browser/ui/webui/options/reset_profile_settings_handler.cc b/chrome/browser/ui/webui/options/reset_profile_settings_handler.cc
index 1d69d5f..5b115ff 100644
--- a/chrome/browser/ui/webui/options/reset_profile_settings_handler.cc
+++ b/chrome/browser/ui/webui/options/reset_profile_settings_handler.cc
@@ -11,8 +11,6 @@
 #include "base/strings/string16.h"
 #include "base/values.h"
 #include "chrome/browser/google/google_brand.h"
-#include "chrome/browser/profile_resetter/automatic_profile_resetter.h"
-#include "chrome/browser/profile_resetter/automatic_profile_resetter_factory.h"
 #include "chrome/browser/profile_resetter/brandcode_config_fetcher.h"
 #include "chrome/browser/profile_resetter/brandcoded_default_settings.h"
 #include "chrome/browser/profile_resetter/profile_resetter.h"
@@ -32,9 +30,7 @@
 
 namespace options {
 
-ResetProfileSettingsHandler::ResetProfileSettingsHandler()
-    : automatic_profile_resetter_(NULL),
-      has_shown_confirmation_dialog_(false) {
+ResetProfileSettingsHandler::ResetProfileSettingsHandler() {
   google_brand::GetBrand(&brandcode_);
 }
 
@@ -43,25 +39,12 @@
 void ResetProfileSettingsHandler::InitializeHandler() {
   Profile* profile = Profile::FromWebUI(web_ui());
   resetter_.reset(new ProfileResetter(profile));
-  automatic_profile_resetter_ =
-      AutomaticProfileResetterFactory::GetForBrowserContext(profile);
 }
 
 void ResetProfileSettingsHandler::InitializePage() {
   web_ui()->CallJavascriptFunction(
       "ResetProfileSettingsOverlay.setResettingState",
       base::FundamentalValue(resetter_->IsActive()));
-  if (automatic_profile_resetter_ &&
-      automatic_profile_resetter_->ShouldShowResetBanner()) {
-    web_ui()->CallJavascriptFunction("ResetProfileSettingsBanner.show");
-  }
-}
-
-void ResetProfileSettingsHandler::Uninitialize() {
-  if (has_shown_confirmation_dialog_ && automatic_profile_resetter_) {
-    automatic_profile_resetter_->NotifyDidCloseWebUIResetDialog(
-        false /*performed_reset*/);
-  }
 }
 
 void ResetProfileSettingsHandler::GetLocalizedValues(
@@ -69,8 +52,6 @@
   DCHECK(localized_strings);
 
   static OptionsStringResource resources[] = {
-    { "resetProfileSettingsBannerText",
-        IDS_RESET_PROFILE_SETTINGS_BANNER_TEXT },
     { "resetProfileSettingsCommit", IDS_RESET_PROFILE_SETTINGS_COMMIT_BUTTON },
     { "resetProfileSettingsExplanation",
         IDS_RESET_PROFILE_SETTINGS_EXPLANATION },
@@ -131,10 +112,6 @@
   web_ui()->RegisterMessageCallback("onHideResetProfileDialog",
       base::Bind(&ResetProfileSettingsHandler::OnHideResetProfileDialog,
                  base::Unretained(this)));
-  web_ui()->RegisterMessageCallback("onDismissedResetProfileSettingsBanner",
-      base::Bind(&ResetProfileSettingsHandler::
-                 OnDismissedResetProfileSettingsBanner,
-                 base::Unretained(this)));
 }
 
 void ResetProfileSettingsHandler::HandleResetProfileSettings(
@@ -166,17 +143,10 @@
       setting_snapshot_->Subtract(current_snapshot);
       std::string report = SerializeSettingsReport(*setting_snapshot_,
                                                    difference);
-      bool is_reset_prompt_active = automatic_profile_resetter_ &&
-          automatic_profile_resetter_->IsResetPromptFlowActive();
-      SendSettingsFeedback(report, profile, is_reset_prompt_active ?
-          PROFILE_RESET_PROMPT : PROFILE_RESET_WEBUI);
+      SendSettingsFeedback(report, profile);
     }
   }
   setting_snapshot_.reset();
-  if (automatic_profile_resetter_) {
-    automatic_profile_resetter_->NotifyDidCloseWebUIResetDialog(
-        true /*performed_reset*/);
-  }
 }
 
 void ResetProfileSettingsHandler::OnShowResetProfileDialog(
@@ -189,10 +159,6 @@
     UpdateFeedbackUI();
   }
 
-  if (automatic_profile_resetter_)
-    automatic_profile_resetter_->NotifyDidOpenWebUIResetDialog();
-  has_shown_confirmation_dialog_ = true;
-
   if (brandcode_.empty())
     return;
   config_fetcher_.reset(new BrandcodeConfigFetcher(
@@ -208,12 +174,6 @@
     setting_snapshot_.reset();
 }
 
-void ResetProfileSettingsHandler::OnDismissedResetProfileSettingsBanner(
-    const base::ListValue* args) {
-  if (automatic_profile_resetter_)
-    automatic_profile_resetter_->NotifyDidCloseWebUIResetBanner();
-}
-
 void ResetProfileSettingsHandler::OnSettingsFetched() {
   DCHECK(config_fetcher_);
   DCHECK(!config_fetcher_->IsActive());
diff --git a/chrome/browser/ui/webui/options/reset_profile_settings_handler.h b/chrome/browser/ui/webui/options/reset_profile_settings_handler.h
index e4e3440..5c1bf2d 100644
--- a/chrome/browser/ui/webui/options/reset_profile_settings_handler.h
+++ b/chrome/browser/ui/webui/options/reset_profile_settings_handler.h
@@ -17,7 +17,6 @@
 class ListValue;
 }  // namespace base
 
-class AutomaticProfileResetter;
 class BrandcodeConfigFetcher;
 class ProfileResetter;
 class ResettableSettingsSnapshot;
@@ -37,7 +36,6 @@
   void GetLocalizedValues(base::DictionaryValue* localized_strings) override;
   void InitializeHandler() override;
   void InitializePage() override;
-  void Uninitialize() override;
 
   // WebUIMessageHandler implementation.
   void RegisterMessages() override;
@@ -55,9 +53,6 @@
   // Called when the confirmation box disappears.
   void OnHideResetProfileDialog(const base::ListValue* value);
 
-  // Called when the reset banner is dismissed from the WebUI.
-  void OnDismissedResetProfileSettingsBanner(const base::ListValue* args);
-
   // Called when BrandcodeConfigFetcher completed fetching settings.
   void OnSettingsFetched();
 
@@ -68,14 +63,6 @@
   // Sets new values for the feedback area.
   void UpdateFeedbackUI();
 
-  // Destroyed with the Profile, thus it should outlive us. This will be NULL if
-  // the underlying profile is off-the-record (e.g. in Guest mode on Chrome OS).
-  AutomaticProfileResetter* automatic_profile_resetter_;
-
-  // Records whether or not the Profile Reset confirmation dialog was opened at
-  // least once during the lifetime of the settings page.
-  bool has_shown_confirmation_dialog_;
-
   scoped_ptr<ProfileResetter> resetter_;
 
   scoped_ptr<BrandcodeConfigFetcher> config_fetcher_;
diff --git a/chrome/browser/ui/webui/settings/reset_settings_handler.cc b/chrome/browser/ui/webui/settings/reset_settings_handler.cc
index 73a0783e..53b19a9 100644
--- a/chrome/browser/ui/webui/settings/reset_settings_handler.cc
+++ b/chrome/browser/ui/webui/settings/reset_settings_handler.cc
@@ -11,8 +11,6 @@
 #include "base/strings/string16.h"
 #include "base/values.h"
 #include "chrome/browser/google/google_brand.h"
-#include "chrome/browser/profile_resetter/automatic_profile_resetter.h"
-#include "chrome/browser/profile_resetter/automatic_profile_resetter_factory.h"
 #include "chrome/browser/profile_resetter/brandcode_config_fetcher.h"
 #include "chrome/browser/profile_resetter/brandcoded_default_settings.h"
 #include "chrome/browser/profile_resetter/profile_resetter.h"
@@ -49,8 +47,6 @@
   google_brand::GetBrand(&brandcode_);
   Profile* profile = Profile::FromWebUI(web_ui);
   resetter_.reset(new ProfileResetter(profile));
-  automatic_profile_resetter_ =
-      AutomaticProfileResetterFactory::GetForBrowserContext(profile);
 
 #if defined(OS_CHROMEOS)
   policy::BrowserPolicyConnectorChromeOS* connector =
@@ -62,12 +58,7 @@
 #endif  // defined(OS_CHROMEOS)
 }
 
-ResetSettingsHandler::~ResetSettingsHandler() {
-  if (has_shown_confirmation_dialog_ && automatic_profile_resetter_) {
-    automatic_profile_resetter_->NotifyDidCloseWebUIResetDialog(
-        false /*performed_reset*/);
-  }
-}
+ResetSettingsHandler::~ResetSettingsHandler() {}
 
 void ResetSettingsHandler::RegisterMessages() {
   web_ui()->RegisterMessageCallback("performResetProfileSettings",
@@ -120,17 +111,10 @@
       setting_snapshot_->Subtract(current_snapshot);
       std::string report = SerializeSettingsReport(*setting_snapshot_,
                                                    difference);
-      bool is_reset_prompt_active = automatic_profile_resetter_ &&
-          automatic_profile_resetter_->IsResetPromptFlowActive();
-      SendSettingsFeedback(report, profile, is_reset_prompt_active ?
-          PROFILE_RESET_PROMPT : PROFILE_RESET_WEBUI);
+      SendSettingsFeedback(report, profile);
     }
   }
   setting_snapshot_.reset();
-  if (automatic_profile_resetter_) {
-    automatic_profile_resetter_->NotifyDidCloseWebUIResetDialog(
-        true /*performed_reset*/);
-  }
 }
 
 void ResetSettingsHandler::OnShowResetProfileDialog(
@@ -143,10 +127,6 @@
     UpdateFeedbackUI();
   }
 
-  if (automatic_profile_resetter_)
-    automatic_profile_resetter_->NotifyDidOpenWebUIResetDialog();
-  has_shown_confirmation_dialog_ = true;
-
   if (brandcode_.empty())
     return;
   config_fetcher_.reset(new BrandcodeConfigFetcher(
diff --git a/chrome/browser/ui/webui/settings/reset_settings_handler.h b/chrome/browser/ui/webui/settings/reset_settings_handler.h
index 2f615b52..0407947 100644
--- a/chrome/browser/ui/webui/settings/reset_settings_handler.h
+++ b/chrome/browser/ui/webui/settings/reset_settings_handler.h
@@ -22,7 +22,6 @@
 class WebUIDataSource;
 }
 
-class AutomaticProfileResetter;
 class BrandcodeConfigFetcher;
 class ProfileResetter;
 class ResettableSettingsSnapshot;
@@ -78,14 +77,6 @@
   bool allow_powerwash_ = false;
 #endif  // defined(OS_CHROMEOS)
 
-  // Destroyed with the Profile, thus it should outlive us. This will be NULL if
-  // the underlying profile is off-the-record (e.g. in Guest mode on Chrome OS).
-  AutomaticProfileResetter* automatic_profile_resetter_ = nullptr;
-
-  // Records whether or not the Profile Reset confirmation dialog was opened at
-  // least once during the lifetime of the settings page.
-  bool has_shown_confirmation_dialog_ = false;
-
   scoped_ptr<ProfileResetter> resetter_;
 
   scoped_ptr<BrandcodeConfigFetcher> config_fetcher_;
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index ffc7bf3..62e9b11 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -1253,25 +1253,10 @@
       'browser/process_singleton_posix.cc',
       'browser/process_singleton_startup_lock.cc',
       'browser/process_singleton_startup_lock.h',
-      'browser/profile_resetter/automatic_profile_resetter.cc',
-      'browser/profile_resetter/automatic_profile_resetter.h',
-      'browser/profile_resetter/automatic_profile_resetter_delegate.cc',
-      'browser/profile_resetter/automatic_profile_resetter_delegate.h',
-      'browser/profile_resetter/automatic_profile_resetter_factory.cc',
-      'browser/profile_resetter/automatic_profile_resetter_factory.h',
-      'browser/profile_resetter/automatic_profile_resetter_mementos.cc',
-      'browser/profile_resetter/automatic_profile_resetter_mementos.h',
       'browser/profile_resetter/brandcode_config_fetcher.cc',
       'browser/profile_resetter/brandcode_config_fetcher.h',
       'browser/profile_resetter/brandcoded_default_settings.cc',
       'browser/profile_resetter/brandcoded_default_settings.h',
-      'browser/profile_resetter/jtl_foundation.cc',
-      'browser/profile_resetter/jtl_foundation.h',
-      'browser/profile_resetter/jtl_instructions.h',
-      'browser/profile_resetter/jtl_interpreter.cc',
-      'browser/profile_resetter/jtl_interpreter.h',
-      'browser/profile_resetter/profile_reset_global_error.cc',
-      'browser/profile_resetter/profile_reset_global_error.h',
       'browser/profile_resetter/profile_resetter.cc',
       'browser/profile_resetter/profile_resetter.h',
       'browser/profile_resetter/resettable_settings_snapshot.cc',
diff --git a/chrome/chrome_browser_chromeos.gypi b/chrome/chrome_browser_chromeos.gypi
index 719f40d..2ed0784 100644
--- a/chrome/chrome_browser_chromeos.gypi
+++ b/chrome/chrome_browser_chromeos.gypi
@@ -112,6 +112,8 @@
         'browser/chromeos/display/output_protection_delegate.h',
         'browser/chromeos/display/overscan_calibrator.cc',
         'browser/chromeos/display/overscan_calibrator.h',
+        'browser/chromeos/policy/display_rotation_default_handler.cc',
+        'browser/chromeos/policy/display_rotation_default_handler.h',
         'browser/chromeos/drive/debug_info_collector.cc',
         'browser/chromeos/drive/debug_info_collector.h',
         'browser/chromeos/drive/download_handler.cc',
diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi
index 03b508f..fdddd1c9 100644
--- a/chrome/chrome_browser_ui.gypi
+++ b/chrome/chrome_browser_ui.gypi
@@ -2347,8 +2347,6 @@
       'browser/ui/views/profiles/avatar_menu_button.h',
       'browser/ui/views/profiles/profile_chooser_view.cc',
       'browser/ui/views/profiles/profile_chooser_view.h',
-      'browser/ui/views/profiles/profile_reset_bubble_view.cc',
-      'browser/ui/views/profiles/profile_reset_bubble_view.h',
       'browser/ui/views/profiles/supervised_user_avatar_label.cc',
       'browser/ui/views/profiles/supervised_user_avatar_label.h',
       'browser/ui/views/profiles/user_manager_view.cc',
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index 6520a78..c8cd2c92 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -790,6 +790,8 @@
       'browser/chromeos/net/network_portal_detector_impl_browsertest.cc',
       'browser/chromeos/ownership/fake_owner_settings_service.cc',
       'browser/chromeos/ownership/fake_owner_settings_service.h',
+      'browser/chromeos/policy/affiliation_test_helper.cc',
+      'browser/chromeos/policy/affiliation_test_helper.h',
       'browser/chromeos/policy/blocking_login_browsertest.cc',
       'browser/chromeos/policy/device_cloud_policy_browsertest.cc',
       'browser/chromeos/policy/device_local_account_browsertest.cc',
@@ -797,6 +799,7 @@
       'browser/chromeos/policy/device_policy_cros_browser_test.h',
       'browser/chromeos/policy/device_status_collector_browsertest.cc',
       'browser/chromeos/policy/device_system_use_24hour_clock_browsertest.cc',
+      'browser/chromeos/policy/display_rotation_default_handler_browsertest.cc',
       'browser/chromeos/policy/force_maximize_on_first_run_chromeos_browsertest.cc',
       'browser/chromeos/policy/login_policy_test_base.cc',
       'browser/chromeos/policy/login_policy_test_base.h',
@@ -804,6 +807,7 @@
       'browser/chromeos/policy/policy_cert_verifier_browsertest.cc',
       'browser/chromeos/policy/power_policy_browsertest.cc',
       'browser/chromeos/policy/restore_on_startup_browsertest_chromeos.cc',
+      'browser/chromeos/policy/user_affiliation_browsertest.cc',
       'browser/chromeos/policy/user_cloud_external_data_manager_browsertest.cc',
       'browser/chromeos/policy/user_cloud_policy_manager_chromeos_browsertest.cc',
       'browser/chromeos/policy/user_policy_test_helper.cc',
@@ -3235,7 +3239,7 @@
           ],
         },
         {
-         'target_name': 'telemetry_perf_unittests',
+         'target_name': 'telemetry_perf_unittests_run',
          'type': 'none',
          'dependencies': [
             'chrome_run',
@@ -3249,7 +3253,7 @@
           ],
         },
         {
-         'target_name': 'telemetry_gpu_unittests',
+         'target_name': 'telemetry_gpu_unittests_run',
          'type': 'none',
          'dependencies': [
             '../content/content_shell_and_tests.gyp:telemetry_base',
diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi
index eb28aa8d..8cec80c1 100644
--- a/chrome/chrome_tests_unit.gypi
+++ b/chrome/chrome_tests_unit.gypi
@@ -2680,7 +2680,6 @@
         }, { # 'OS!="android" and OS!="ios"'
           'dependencies': [
             '../components/components.gyp:bubble_test_support',
-            'tools/profile_reset/jtl_compiler.gyp:jtl_compiler_lib',
           ],
         }],
         ['OS != "android" and chromeos == 0', {
diff --git a/chrome/common/chrome_constants.cc b/chrome/common/chrome_constants.cc
index 49e4009a..ab1c7e3 100644
--- a/chrome/common/chrome_constants.cc
+++ b/chrome/common/chrome_constants.cc
@@ -159,8 +159,6 @@
 const base::FilePath::CharType kProtectedPreferencesFilenameDeprecated[] =
     FPL("Protected Preferences");
 const base::FilePath::CharType kReadmeFilename[] = FPL("README");
-const base::FilePath::CharType kResetPromptMementoFilename[] =
-    FPL("Reset Prompt Memento");
 const base::FilePath::CharType kSafeBrowsingBaseFilename[] =
     FPL("Safe Browsing");
 const base::FilePath::CharType kSecurePreferencesFilename[] =
diff --git a/chrome/common/chrome_constants.h b/chrome/common/chrome_constants.h
index 933a3c3..33b4008 100644
--- a/chrome/common/chrome_constants.h
+++ b/chrome/common/chrome_constants.h
@@ -72,7 +72,6 @@
 extern const base::FilePath::CharType kPreferencesFilename[];
 extern const base::FilePath::CharType kProtectedPreferencesFilenameDeprecated[];
 extern const base::FilePath::CharType kReadmeFilename[];
-extern const base::FilePath::CharType kResetPromptMementoFilename[];
 extern const base::FilePath::CharType kSafeBrowsingBaseFilename[];
 extern const base::FilePath::CharType kSecurePreferencesFilename[];
 extern const base::FilePath::CharType kServiceStateFileName[];
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index 94952ba..442529f9 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -1121,11 +1121,6 @@
 // List pref containing the users supervised by this user.
 const char kSupervisedUsers[] = "profile.managed_users";
 
-// String that indicates that the profile reset prompt has already been shown to
-// the user (profile).
-const char kProfileResetPromptMementoInProfilePrefs[] =
-    "profile.reset_prompt_memento";
-
 // List pref containing the extension ids which are not allowed to send
 // notifications to the message center.
 const char kMessageCenterDisabledExtensionIds[] =
@@ -1246,14 +1241,6 @@
 // them.
 const char kProfileInfoCache[] = "profile.info_cache";
 
-// Dictionary that maps profile keys to strings that indicate that the profile
-// reset prompt has already been shown to the corresponding user (profile).
-// This is semantically similar to kProfileResetPromptMementoInProfilePrefs, see
-// chrome/browser/profile_resetter/automatic_profile_resetter_mementos.h for an
-// explanation of why this redundancy is needed.
-const char kProfileResetPromptMementosInLocalState[] =
-    "profile.reset_prompt_mementos";
-
 // Boolean that specifies whether or not crash reports are sent
 // over the network for analysis.
 #if defined(OS_ANDROID)
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index 7c200ed..0f8d51a 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -379,8 +379,6 @@
 extern const char kSupervisedUserCreationAllowed[];
 extern const char kSupervisedUsers[];
 
-extern const char kProfileResetPromptMementoInProfilePrefs[];
-
 extern const char kMessageCenterDisabledExtensionIds[];
 extern const char kMessageCenterDisabledSystemComponentIds[];
 extern const char kWelcomeNotificationDismissed[];
@@ -430,7 +428,6 @@
 extern const char kProfilesNumCreated[];
 extern const char kProfileInfoCache[];
 extern const char kProfileCreatedByVersion[];
-extern const char kProfileResetPromptMementosInLocalState[];
 
 extern const char kStabilityOtherUserCrashCount[];
 extern const char kStabilityKernelCrashCount[];
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index df501b27..85dddc40 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -2006,8 +2006,6 @@
       "../browser/ui/bookmarks/bookmark_ui_utils_desktop_unittest.cc",
       "../browser/ui/sync/sync_promo_ui_unittest.cc",
     ]
-  } else {
-    deps += [ "//chrome/tools/profile_reset:jtl_compiler_lib" ]
   }
   if (!is_android && !is_chromeos) {
     sources += rebase_path(
@@ -2104,7 +2102,6 @@
       "../common/crash_keys.cc",
       "../common/crash_keys.h",
     ]
-
     deps = [
       ":test_support",
       "//breakpad:client",
diff --git a/chrome/test/base/test_browser_window.cc b/chrome/test/base/test_browser_window.cc
index 41dbb5c..3175183c 100644
--- a/chrome/test/base/test_browser_window.cc
+++ b/chrome/test/base/test_browser_window.cc
@@ -177,15 +177,6 @@
   return nullptr;
 }
 
-bool TestBrowserWindow::IsProfileResetBubbleSupported() const {
-  return false;
-}
-
-GlobalErrorBubbleViewBase* TestBrowserWindow::ShowProfileResetBubble(
-    const base::WeakPtr<ProfileResetGlobalError>& global_error) {
-  return nullptr;
-}
-
 bool TestBrowserWindow::IsDownloadShelfVisible() const {
   return false;
 }
diff --git a/chrome/test/base/test_browser_window.h b/chrome/test/base/test_browser_window.h
index 0bce5fac..0e4bfcda 100644
--- a/chrome/test/base/test_browser_window.h
+++ b/chrome/test/base/test_browser_window.h
@@ -119,9 +119,6 @@
                            translate::TranslateStep step,
                            translate::TranslateErrors::Type error_type,
                            bool is_user_gesture) override {}
-  bool IsProfileResetBubbleSupported() const override;
-  GlobalErrorBubbleViewBase* ShowProfileResetBubble(
-      const base::WeakPtr<ProfileResetGlobalError>& global_error) override;
 #if defined(ENABLE_ONE_CLICK_SIGNIN)
   void ShowOneClickSigninBubble(
       OneClickSigninBubbleType type,
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json
index 7c3fd77..c8aea26 100644
--- a/chrome/test/data/policy/policy_test_cases.json
+++ b/chrome/test/data/policy/policy_test_cases.json
@@ -2383,6 +2383,12 @@
     ]
   },
 
+  "DisplayRotationDefault": {
+    "os": ["chromeos"],
+    "can_be_recommended": false,
+    "test_policy": { "DisplayRotationDefault": 1 }
+  },
+
   "ChromeOsReleaseChannel": {
   },
 
diff --git a/chrome/tools/profile_reset/BUILD.gn b/chrome/tools/profile_reset/BUILD.gn
deleted file mode 100644
index 1cebad1..0000000
--- a/chrome/tools/profile_reset/BUILD.gn
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-executable("jtl_compiler") {
-  sources = [
-    "//chrome/browser/profile_resetter/jtl_foundation.cc",
-    "//chrome/browser/profile_resetter/jtl_foundation.h",
-    "jtl_compiler_frontend.cc",
-  ]
-  deps = [
-    ":jtl_compiler_lib",
-    "//base",
-    "//build/config/sanitizers:deps",
-    "//crypto",
-  ]
-}
-
-source_set("jtl_compiler_lib") {
-  sources = [
-    "//chrome/browser/profile_resetter/jtl_foundation.h",
-    "//chrome/browser/profile_resetter/jtl_instructions.h",
-    "jtl_compiler.cc",
-    "jtl_compiler.h",
-    "jtl_parser.cc",
-    "jtl_parser.h",
-  ]
-  deps = [
-    "//base",
-    "//third_party/re2",
-  ]
-}
diff --git a/chrome/tools/profile_reset/OWNERS b/chrome/tools/profile_reset/OWNERS
deleted file mode 100644
index de6863ee..0000000
--- a/chrome/tools/profile_reset/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-battre@chromium.org
-engedy@chromium.org
-
diff --git a/chrome/tools/profile_reset/jtl_compiler.cc b/chrome/tools/profile_reset/jtl_compiler.cc
deleted file mode 100644
index ffa5ec2..0000000
--- a/chrome/tools/profile_reset/jtl_compiler.cc
+++ /dev/null
@@ -1,252 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/tools/profile_reset/jtl_compiler.h"
-
-#include <limits>
-#include <map>
-#include <numeric>
-
-#include "base/logging.h"
-#include "chrome/browser/profile_resetter/jtl_foundation.h"
-#include "chrome/tools/profile_reset/jtl_parser.h"
-
-namespace jtl = jtl_foundation;
-
-namespace {
-
-// Serializes symbols into byte-code in a streaming manner.
-class ByteCodeWriter {
- public:
-  explicit ByteCodeWriter(std::string* output) : output_(output) {}
-  ~ByteCodeWriter() {}
-
-  void WriteUint8(uint8 value) { output_->push_back(static_cast<char>(value)); }
-  void WriteUint32(uint32 value) {
-    for (int i = 0; i < 4; ++i) {
-      output_->push_back(static_cast<char>(value & 0xFFu));
-      value >>= 8;
-    }
-  }
-  void WriteOpCode(uint8 op_code) { WriteUint8(op_code); }
-  void WriteHash(const std::string& hash) {
-    CHECK(jtl::Hasher::IsHash(hash));
-    *output_ += hash;
-  }
-  void WriteBool(bool value) { WriteUint8(value ? 1u : 0u); }
-
- private:
-  std::string* output_;
-
-  DISALLOW_COPY_AND_ASSIGN(ByteCodeWriter);
-};
-
-// Encapsulates meta-data about all instructions, and is capable of transcoding
-// each instruction from a parsed text-based format to byte-code.
-class InstructionSet {
- public:
-  InstructionSet() {
-    // Define each instruction in this list.
-    // Note:
-    //  - Instructions ending in "hash" will write their 'HashString' arguments
-    //    directly into the byte-code.
-    //  - Instructions ending in "hashed" will first hash their 'String'
-    //    arguments, and will write this hash to the byte-code.
-    Add(Instruction("go", jtl::NAVIGATE, Arguments(String)));
-    Add(Instruction("any", jtl::NAVIGATE_ANY, Arguments()));
-    Add(Instruction("back", jtl::NAVIGATE_BACK, Arguments()));
-    Add(Instruction("store_bool", jtl::STORE_BOOL, Arguments(String, Bool)));
-    Add(Instruction("store_hash",
-                    jtl::STORE_HASH, Arguments(String, HashString)));
-    Add(Instruction("store_hashed",
-                    jtl::STORE_HASH, Arguments(String, String)));
-    Add(Instruction("store_node_bool",
-                    jtl::STORE_NODE_BOOL, Arguments(String)));
-    Add(Instruction("store_node_hash",
-                    jtl::STORE_NODE_HASH, Arguments(String)));
-    Add(Instruction("store_node_registerable_domain_hash",
-                    jtl::STORE_NODE_REGISTERABLE_DOMAIN_HASH,
-                    Arguments(String)));
-    Add(Instruction("compare_bool", jtl::COMPARE_NODE_BOOL, Arguments(Bool)));
-    Add(Instruction("compare_hashed",
-                    jtl::COMPARE_NODE_HASH, Arguments(String)));
-    Add(Instruction("compare_hashed_not",
-                    jtl::COMPARE_NODE_HASH_NOT, Arguments(String)));
-    Add(Instruction("compare_stored_bool",
-                    jtl::COMPARE_STORED_BOOL,
-                    Arguments(String, Bool, Bool)));
-    Add(Instruction("compare_stored_hashed",
-                    jtl::COMPARE_STORED_HASH,
-                    Arguments(String, String, String)));
-    Add(Instruction("compare_to_stored_bool",
-                    jtl::COMPARE_NODE_TO_STORED_BOOL,
-                    Arguments(String)));
-    Add(Instruction("compare_to_stored_hash",
-                    jtl::COMPARE_NODE_TO_STORED_HASH,
-                    Arguments(String)));
-    Add(Instruction("compare_substring_hashed",
-                    jtl::COMPARE_NODE_SUBSTRING,
-                    Arguments(StringPattern)));
-    Add(Instruction("break", jtl::STOP_EXECUTING_SENTENCE, Arguments()));
-  }
-
-  JtlCompiler::CompileError::ErrorCode TranscodeInstruction(
-      const std::string& name,
-      const base::ListValue& arguments,
-      bool ends_sentence,
-      const jtl::Hasher& hasher,
-      ByteCodeWriter* target) const {
-    if (instruction_map_.count(name) == 0)
-      return JtlCompiler::CompileError::INVALID_OPERATION_NAME;
-    const Instruction& instruction(instruction_map_.at(name));
-    if (instruction.argument_types.size() != arguments.GetSize())
-      return JtlCompiler::CompileError::INVALID_ARGUMENT_COUNT;
-    target->WriteOpCode(instruction.op_code);
-    for (size_t i = 0; i < arguments.GetSize(); ++i) {
-      switch (instruction.argument_types[i]) {
-        case Bool: {
-          bool value = false;
-          if (!arguments.GetBoolean(i, &value))
-            return JtlCompiler::CompileError::INVALID_ARGUMENT_TYPE;
-          target->WriteBool(value);
-          break;
-        }
-        case String: {
-          std::string value;
-          if (!arguments.GetString(i, &value))
-            return JtlCompiler::CompileError::INVALID_ARGUMENT_TYPE;
-          target->WriteHash(hasher.GetHash(value));
-          break;
-        }
-        case StringPattern: {
-          std::string value;
-          if (!arguments.GetString(i, &value))
-            return JtlCompiler::CompileError::INVALID_ARGUMENT_TYPE;
-          if (value.empty() ||
-              value.size() > std::numeric_limits<uint32>::max())
-            return JtlCompiler::CompileError::INVALID_ARGUMENT_VALUE;
-          target->WriteHash(hasher.GetHash(value));
-          target->WriteUint32(static_cast<uint32>(value.size()));
-          uint32 pattern_sum = std::accumulate(
-              value.begin(), value.end(), static_cast<uint32>(0u));
-          target->WriteUint32(pattern_sum);
-          break;
-        }
-        case HashString: {
-          std::string hash_value;
-          if (!arguments.GetString(i, &hash_value) ||
-              !jtl::Hasher::IsHash(hash_value))
-            return JtlCompiler::CompileError::INVALID_ARGUMENT_TYPE;
-          target->WriteHash(hash_value);
-          break;
-        }
-        default:
-          NOTREACHED();
-          return JtlCompiler::CompileError::INVALID_ARGUMENT_TYPE;
-      }
-    }
-    if (ends_sentence)
-      target->WriteOpCode(jtl::END_OF_SENTENCE);
-    return JtlCompiler::CompileError::ERROR_NONE;
-  }
-
- private:
-  // The possible types of an operation's argument.
-  enum ArgumentType {
-    None,
-    Bool,
-    String,
-    StringPattern,
-    HashString
-  };
-
-  // Encapsulates meta-data about one instruction.
-  struct Instruction {
-    Instruction() : op_code(jtl::END_OF_SENTENCE) {}
-    Instruction(const char* name,
-                jtl_foundation::OpCodes op_code,
-                const std::vector<ArgumentType>& argument_types)
-        : name(name), op_code(op_code), argument_types(argument_types) {}
-
-    std::string name;
-    jtl::OpCodes op_code;
-    std::vector<ArgumentType> argument_types;
-  };
-
-  static std::vector<ArgumentType> Arguments(ArgumentType arg1_type = None,
-                                             ArgumentType arg2_type = None,
-                                             ArgumentType arg3_type = None) {
-    std::vector<ArgumentType> result;
-    if (arg1_type != None)
-      result.push_back(arg1_type);
-    if (arg2_type != None)
-      result.push_back(arg2_type);
-    if (arg3_type != None)
-      result.push_back(arg3_type);
-    return result;
-  }
-
-  void Add(const Instruction& instruction) {
-    instruction_map_[instruction.name] = instruction;
-  }
-
-  std::map<std::string, Instruction> instruction_map_;
-
-  DISALLOW_COPY_AND_ASSIGN(InstructionSet);
-};
-
-}  // namespace
-
-bool JtlCompiler::Compile(const std::string& source_code,
-                          const std::string& hash_seed,
-                          std::string* output_bytecode,
-                          CompileError* error_details) {
-  DCHECK(output_bytecode);
-  InstructionSet instruction_set;
-  ByteCodeWriter bytecode_writer(output_bytecode);
-  jtl::Hasher hasher(hash_seed);
-
-  std::string compacted_source_code;
-  std::vector<size_t> newline_indices;
-  size_t mismatched_quotes_line;
-  if (!JtlParser::RemoveCommentsAndAllWhitespace(source_code,
-                                                 &compacted_source_code,
-                                                 &newline_indices,
-                                                 &mismatched_quotes_line)) {
-    if (error_details) {
-      error_details->context = "";  // No meaningful intra-line context here.
-      error_details->line_number = mismatched_quotes_line;
-      error_details->error_code = CompileError::MISMATCHED_DOUBLE_QUOTES;
-    }
-    return false;
-  }
-
-  JtlParser parser(compacted_source_code, newline_indices);
-  while (!parser.HasFinished()) {
-    std::string operation_name;
-    base::ListValue arguments;
-    bool ends_sentence = false;
-    if (!parser.ParseNextOperation(
-             &operation_name, &arguments, &ends_sentence)) {
-      if (error_details) {
-        error_details->context = parser.GetLastContext();
-        error_details->line_number = parser.GetLastLineNumber();
-        error_details->error_code = CompileError::PARSING_ERROR;
-      }
-      return false;
-    }
-    CompileError::ErrorCode error_code = instruction_set.TranscodeInstruction(
-        operation_name, arguments, ends_sentence, hasher, &bytecode_writer);
-    if (error_code != CompileError::ERROR_NONE) {
-      if (error_details) {
-        error_details->context = parser.GetLastContext();
-        error_details->line_number = parser.GetLastLineNumber();
-        error_details->error_code = error_code;
-      }
-      return false;
-    }
-  }
-
-  return true;
-}
diff --git a/chrome/tools/profile_reset/jtl_compiler.gyp b/chrome/tools/profile_reset/jtl_compiler.gyp
deleted file mode 100644
index 40dca37..0000000
--- a/chrome/tools/profile_reset/jtl_compiler.gyp
+++ /dev/null
@@ -1,40 +0,0 @@
-{
-  'variables': {
-    'chromium_code': 1,
-  },
-  'targets': [
-    {
-      # GN version: //chrome/tools/profile_reset:jtl_compiler
-      'target_name': 'jtl_compiler',
-      'type': 'executable',
-      'dependencies': [
-        '../../../base/base.gyp:base',
-        '../../../crypto/crypto.gyp:crypto',
-        'jtl_compiler_lib',
-      ],
-      'sources': [
-        '../../browser/profile_resetter/jtl_foundation.cc',
-        '../../browser/profile_resetter/jtl_foundation.h',
-        'jtl_compiler_frontend.cc',
-      ],
-    },
-    {
-      # GN version: //chrome/tools/profile_reset:jtl_compiler_lib
-      'target_name': 'jtl_compiler_lib',
-      'type': 'static_library',
-      'product_name': 'jtl_compiler',
-      'dependencies': [
-        '../../../third_party/re2/re2.gyp:re2',
-        '../../../base/base.gyp:base',
-      ],
-      'sources': [
-        '../../browser/profile_resetter/jtl_foundation.h',
-        '../../browser/profile_resetter/jtl_instructions.h',
-        'jtl_compiler.cc',
-        'jtl_compiler.h',
-        'jtl_parser.cc',
-        'jtl_parser.h',
-      ],
-    },
-  ],
-}
diff --git a/chrome/tools/profile_reset/jtl_compiler.h b/chrome/tools/profile_reset/jtl_compiler.h
deleted file mode 100644
index cd81b81f..0000000
--- a/chrome/tools/profile_reset/jtl_compiler.h
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_TOOLS_PROFILE_RESET_JTL_COMPILER_H_
-#define CHROME_TOOLS_PROFILE_RESET_JTL_COMPILER_H_
-
-#include <string>
-
-#include "base/basictypes.h"
-
-// Compiles text-based JTL source code into JTL byte-code.
-//
-// For an overview of JTL (JSON Traversal Language), and the exhaustive list of
-// instructions, please see "chrome/browser/profile_resetter/jtl_foundation.h".
-//
-// The text-based JTL syntax itself much resembles C/C++. A program consists of
-// zero or more sentences. Each sentence is terminated by a semi-colon (;), and
-// is composed of *one* or more operations, separated by periods (.).
-//
-// Each operation resembles a C/C++ function call and consists of an instruction
-// name, and an optional argument list, which takes Boolean values and/or string
-// literals. The text-based instruction names are defined in "jtl_compiler.cc".
-//
-// Whitespace does not matter, except for inside string literals. C++-style,
-// double-slash-introduced comments are also supported.
-//
-// Example source code:
-//
-//   // Store "x"=true if path "foo.bar" is found.
-//   go("foo").go("bar").store_bool("x", true);
-//
-//   // Store "y"="1" if the above value is set.
-//   compare_stored_bool("x", true, false).store_hash("y", "1");
-//
-class JtlCompiler {
- public:
-  struct CompileError {
-    enum ErrorCode {
-      ERROR_NONE,
-      MISMATCHED_DOUBLE_QUOTES,
-      PARSING_ERROR,
-      INVALID_OPERATION_NAME,
-      INVALID_ARGUMENT_COUNT,
-      INVALID_ARGUMENT_TYPE,
-      INVALID_ARGUMENT_VALUE
-    };
-
-    CompileError() : line_number(0), error_code(ERROR_NONE) {}
-    CompileError(size_t line_number,
-                 const std::string& context,
-                 ErrorCode error_code)
-        : line_number(line_number), context(context), error_code(error_code) {}
-
-    size_t line_number;  // 0-based.
-    std::string context;
-    ErrorCode error_code;
-  };
-
-  // Compiles text-based JTL source code contained in |source_code| into JTL
-  // byte-code to |output_bytecode|. Variable, node names, and string literals
-  // will be hashed using the seed in |hash_seed|.
-  // On success, returns true. Otherwise, returns false and fills |error| with
-  // more information (if it is non-NULL).
-  static bool Compile(const std::string& source_code,
-                      const std::string& hash_seed,
-                      std::string* output_bytecode,
-                      CompileError* error);
-
- private:
-  DISALLOW_IMPLICIT_CONSTRUCTORS(JtlCompiler);
-};
-
-#endif  // CHROME_TOOLS_PROFILE_RESET_JTL_COMPILER_H_
diff --git a/chrome/tools/profile_reset/jtl_compiler_frontend.cc b/chrome/tools/profile_reset/jtl_compiler_frontend.cc
deleted file mode 100644
index 634d3a7c..0000000
--- a/chrome/tools/profile_reset/jtl_compiler_frontend.cc
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// A simple command-line compiler for JTL (JSON Traversal Language).
-//
-// Translates rules from a text-based, human-readable format to an easy-to-parse
-// byte-code format, which then can be interpreted by JtlInterpreter.
-//
-// Example usage:
-//   jtl_compiler --input=blah.txt --hash-seed="foobar" --output=blah.dat
-
-#include <iostream>
-#include <string>
-
-#include "base/command_line.h"
-#include "base/files/file_path.h"
-#include "base/files/file_util.h"
-#include "chrome/tools/profile_reset/jtl_compiler.h"
-
-namespace {
-
-// Command-line argument name: path to the input text-based JTL source code.
-const char kInputPath[] = "input";
-
-// Command-line argument name: path to the output byte-code.
-const char kOutputPath[] = "output";
-
-// Command-line argument name: the hash seed to use.
-const char kHashSeed[] = "hash-seed";
-
-// Error codes.
-const char kMismatchedDoubleQuotes[] = "Mismatched double-quotes before EOL.";
-const char kParsingError[] = "Parsing error. Input is ill-formed.";
-const char kArgumentCountError[] = "Wrong number of arguments for operation.";
-const char kArgumentTypeError[] = "Wrong argument type(s) for operation.";
-const char kArgumentValueError[] = "Wrong argument value(s) for operation.";
-const char kUnknownOperationError[] = "No operation by this name.";
-const char kUnknownError[] = "Unknown error.";
-
-const char* ResolveErrorCode(JtlCompiler::CompileError::ErrorCode code) {
-  switch (code) {
-    case JtlCompiler::CompileError::MISMATCHED_DOUBLE_QUOTES:
-      return kMismatchedDoubleQuotes;
-    case JtlCompiler::CompileError::PARSING_ERROR:
-      return kParsingError;
-    case JtlCompiler::CompileError::INVALID_ARGUMENT_COUNT:
-      return kArgumentCountError;
-    case JtlCompiler::CompileError::INVALID_ARGUMENT_TYPE:
-      return kArgumentTypeError;
-    case JtlCompiler::CompileError::INVALID_ARGUMENT_VALUE:
-      return kArgumentValueError;
-    case JtlCompiler::CompileError::INVALID_OPERATION_NAME:
-      return kUnknownOperationError;
-    default:
-      return kUnknownError;
-  }
-}
-
-}  // namespace
-
-int main(int argc, char* argv[]) {
-  base::CommandLine::Init(argc, argv);
-  base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
-  if (!cmd_line->HasSwitch(kInputPath) || !cmd_line->HasSwitch(kHashSeed) ||
-      !cmd_line->HasSwitch(kOutputPath)) {
-    std::cerr << "Usage: " << argv[0] << " <required switches>" << std::endl;
-    std::cerr << "\nRequired switches are:" << std::endl;
-    std::cerr << "  --" << kInputPath << "=<file>"
-              << "\t\tPath to the input text-based JTL source code."
-              << std::endl;
-    std::cerr << "  --" << kOutputPath << "=<file>"
-              << "\t\tPath to the output byte-code." << std::endl;
-    std::cerr << "  --" << kHashSeed << "=<value>"
-              << "\t\tThe hash seed to use." << std::endl;
-    return -1;
-  }
-
-  base::FilePath source_code_path =
-      MakeAbsoluteFilePath(cmd_line->GetSwitchValuePath(kInputPath));
-  std::string source_code;
-  if (!base::ReadFileToString(source_code_path, &source_code)) {
-    std::cerr << "ERROR: Cannot read input file." << std::endl;
-    return -3;
-  }
-
-  std::string bytecode;
-  JtlCompiler::CompileError error;
-  std::string hash_seed = cmd_line->GetSwitchValueASCII(kHashSeed);
-  if (!JtlCompiler::Compile(source_code, hash_seed, &bytecode, &error)) {
-    std::cerr << "COMPILE ERROR: " << ResolveErrorCode(error.error_code)
-              << std::endl;
-    std::cerr << "  Line number: " << (error.line_number + 1) << std::endl;
-    std::cerr << "  Context: " << (error.context.size() > 63
-                                       ? error.context.substr(0, 60) + "..."
-                                       : error.context) << std::endl;
-    return -2;
-  }
-
-  base::FilePath bytecode_path =
-      MakeAbsoluteFilePath(cmd_line->GetSwitchValuePath(kOutputPath));
-  int bytes_written =
-      base::WriteFile(cmd_line->GetSwitchValuePath(kOutputPath),
-                           bytecode.data(),
-                           static_cast<int>(bytecode.size()));
-  if (bytes_written != static_cast<int>(bytecode.size())) {
-    std::cerr << "ERROR: Cannot write output file." << std::endl;
-    return -3;
-  }
-
-  return 0;
-}
diff --git a/chrome/tools/profile_reset/jtl_compiler_unittest.cc b/chrome/tools/profile_reset/jtl_compiler_unittest.cc
deleted file mode 100644
index c39e59a4..0000000
--- a/chrome/tools/profile_reset/jtl_compiler_unittest.cc
+++ /dev/null
@@ -1,218 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/tools/profile_reset/jtl_compiler.h"
-
-#include <string>
-
-#include "base/values.h"
-#include "chrome/browser/profile_resetter/jtl_foundation.h"
-#include "chrome/browser/profile_resetter/jtl_instructions.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace {
-
-const char kTestHashSeed[] = "test-hash-seed";
-
-// Helpers -------------------------------------------------------------------
-
-std::string GetHash(const std::string& input) {
-  return jtl_foundation::Hasher(kTestHashSeed).GetHash(input);
-}
-
-static std::string EncodeUint32(uint32 value) {
-  std::string bytecode;
-  for (int i = 0; i < 4; ++i) {
-    bytecode.push_back(static_cast<char>(value & 0xFFu));
-    value >>= 8;
-  }
-  return bytecode;
-}
-
-// Tests ---------------------------------------------------------------------
-
-// Note: Parsing and parsing-related errors are unit-tested separately in more
-// detail in "jtl_parser_unittest.cc". Here, most of  the time, we assume that
-// creating the parse tree works.
-
-TEST(JtlCompiler, CompileSingleInstructions) {
-  struct TestCase {
-    std::string source_code;
-    std::string expected_bytecode;
-  } cases[] = {
-        {"go(\"foo\").", OP_NAVIGATE(GetHash("foo"))},
-        {"go(\"has whitespace\t\").", OP_NAVIGATE(GetHash("has whitespace\t"))},
-        {"any.", OP_NAVIGATE_ANY},
-        {"back.", OP_NAVIGATE_BACK},
-        {"store_bool(\"name\", true).",
-         OP_STORE_BOOL(GetHash("name"), VALUE_TRUE)},
-        {"compare_stored_bool(\"name\", true, false).",
-         OP_COMPARE_STORED_BOOL(GetHash("name"), VALUE_TRUE, VALUE_FALSE)},
-        {"store_hash(\"name\", \"" + GetHash("value") + "\").",
-         OP_STORE_HASH(GetHash("name"), GetHash("value"))},
-        {"store_hashed(\"name\", \"value\").",
-         OP_STORE_HASH(GetHash("name"), GetHash("value"))},
-        {"store_node_bool(\"name\").", OP_STORE_NODE_BOOL(GetHash("name"))},
-        {"store_node_hash(\"name\").", OP_STORE_NODE_HASH(GetHash("name"))},
-        {"store_node_registerable_domain_hash(\"name\").",
-         OP_STORE_NODE_REGISTERABLE_DOMAIN_HASH(GetHash("name"))},
-        {"compare_stored_hashed(\"name\", \"value\", \"default\").",
-         OP_COMPARE_STORED_HASH(
-             GetHash("name"), GetHash("value"), GetHash("default"))},
-        {"compare_bool(false).", OP_COMPARE_NODE_BOOL(VALUE_FALSE)},
-        {"compare_bool(true).", OP_COMPARE_NODE_BOOL(VALUE_TRUE)},
-        {"compare_hashed(\"foo\").", OP_COMPARE_NODE_HASH(GetHash("foo"))},
-        {"compare_hashed_not(\"foo\").",
-         OP_COMPARE_NODE_HASH_NOT(GetHash("foo"))},
-        {"compare_to_stored_bool(\"name\").",
-         OP_COMPARE_NODE_TO_STORED_BOOL(GetHash("name"))},
-        {"compare_to_stored_hash(\"name\").",
-         OP_COMPARE_NODE_TO_STORED_HASH(GetHash("name"))},
-        {"compare_substring_hashed(\"pattern\").",
-         OP_COMPARE_NODE_SUBSTRING(
-             GetHash("pattern"), EncodeUint32(7), EncodeUint32(766))},
-        {"break.", OP_STOP_EXECUTING_SENTENCE},
-        {"break;", OP_STOP_EXECUTING_SENTENCE + OP_END_OF_SENTENCE}};
-
-  for (size_t i = 0; i < arraysize(cases); ++i) {
-    SCOPED_TRACE(cases[i].source_code);
-    std::string bytecode;
-    EXPECT_TRUE(JtlCompiler::Compile(
-        cases[i].source_code, kTestHashSeed, &bytecode, NULL));
-    EXPECT_EQ(cases[i].expected_bytecode, bytecode);
-  }
-}
-
-TEST(JtlCompiler, CompileEntireProgram) {
-  const char kSourceCode[] =
-      "// Store \"x\"=true if path is found.\n"
-      "go(\"foo\").go(\"bar\").store_bool(\"x\", true);\n"
-      "// ...\n"
-      "// Store \"y\"=\"1\" if above value is set.\n"
-      "compare_stored_bool(\"x\", true, false).store_hashed(\"y\", \"1\");\n";
-
-  std::string expected_bytecode =
-      OP_NAVIGATE(GetHash("foo")) +
-      OP_NAVIGATE(GetHash("bar")) +
-      OP_STORE_BOOL(GetHash("x"), VALUE_TRUE) + OP_END_OF_SENTENCE +
-      OP_COMPARE_STORED_BOOL(GetHash("x"), VALUE_TRUE, VALUE_FALSE) +
-      OP_STORE_HASH(GetHash("y"), GetHash("1")) + OP_END_OF_SENTENCE;
-
-  std::string bytecode;
-  EXPECT_TRUE(
-      JtlCompiler::Compile(kSourceCode, kTestHashSeed, &bytecode, NULL));
-  EXPECT_EQ(expected_bytecode, bytecode);
-}
-
-TEST(JtlCompiler, InvalidOperationName) {
-  const char kSourceCode[] = "any()\n.\nnon_existent_instruction\n(\n)\n;\n";
-
-  std::string bytecode;
-  JtlCompiler::CompileError error;
-  EXPECT_FALSE(
-      JtlCompiler::Compile(kSourceCode, kTestHashSeed, &bytecode, &error));
-  EXPECT_THAT(error.context,
-              testing::base::StartsWith("non_existent_instruction"));
-  EXPECT_EQ(2u, error.line_number);
-  EXPECT_EQ(JtlCompiler::CompileError::INVALID_OPERATION_NAME,
-            error.error_code);
-}
-
-TEST(JtlCompiler, InvalidArgumentsCount) {
-  const char* const kSourceCodes[] = {
-      "any().\nstore_bool(\"name\", true, \"superfluous argument\");\n",
-      "any().\nstore_bool(\"name\");"};  // missing argument
-
-  for (size_t i = 0; i < arraysize(kSourceCodes); ++i) {
-    SCOPED_TRACE(kSourceCodes[i]);
-    std::string bytecode;
-    JtlCompiler::CompileError error;
-    EXPECT_FALSE(JtlCompiler::Compile(
-        kSourceCodes[i], kTestHashSeed, &bytecode, &error));
-    EXPECT_THAT(error.context, testing::base::StartsWith("store_bool"));
-    EXPECT_EQ(1u, error.line_number);
-    EXPECT_EQ(JtlCompiler::CompileError::INVALID_ARGUMENT_COUNT,
-              error.error_code);
-  }
-}
-
-TEST(JtlCompiler, InvalidArgumentType) {
-  struct TestCase {
-    std::string expected_context_prefix;
-    std::string source_code;
-  } cases[] = {
-        {"compare_bool", "any()\n.\ncompare_bool(\"foo\");"},
-        {"compare_bool",
-         "any()\n.\ncompare_bool(\"01234567890123456789012345678901\");"},
-        {"compare_hashed", "any()\n.\ncompare_hashed(false);"},
-        {"store_hash", "any()\n.\nstore_hash(\"name\", false);"},
-        {"store_hash", "any()\n.\nstore_hash(\"name\", \"foo\");"},
-        {"compare_stored_bool",
-         "any()\n.\ncompare_stored_bool(\"name\", \"need a bool\", false);"},
-        {"compare_stored_bool",
-         "any()\n.\ncompare_stored_bool(\"name\", false, \"need a bool\");"},
-        {"compare_substring_hashed",
-         "any()\n.\ncompare_substring_hashed(true);"}};
-
-  for (size_t i = 0; i < arraysize(cases); ++i) {
-    SCOPED_TRACE(cases[i].source_code);
-    std::string bytecode;
-    JtlCompiler::CompileError error;
-    EXPECT_FALSE(JtlCompiler::Compile(
-        cases[i].source_code, kTestHashSeed, &bytecode, &error));
-    EXPECT_THAT(error.context,
-                testing::base::StartsWith(cases[i].expected_context_prefix));
-    EXPECT_EQ(2u, error.line_number);
-    EXPECT_EQ(JtlCompiler::CompileError::INVALID_ARGUMENT_TYPE,
-              error.error_code);
-  }
-}
-
-TEST(JtlCompiler, InvalidArgumentValue) {
-  struct TestCase {
-    std::string expected_context_prefix;
-    std::string source_code;
-  } cases[] = {
-        {"compare_substring_hashed", "compare_substring_hashed(\"\");"}};
-
-  for (size_t i = 0; i < arraysize(cases); ++i) {
-    SCOPED_TRACE(cases[i].source_code);
-    std::string bytecode;
-    JtlCompiler::CompileError error;
-    EXPECT_FALSE(JtlCompiler::Compile(
-        cases[i].source_code, kTestHashSeed, &bytecode, &error));
-    EXPECT_THAT(error.context,
-                testing::base::StartsWith(cases[i].expected_context_prefix));
-    EXPECT_EQ(0u, error.line_number);
-    EXPECT_EQ(JtlCompiler::CompileError::INVALID_ARGUMENT_VALUE,
-              error.error_code);
-  }
-}
-
-TEST(JtlCompiler, MistmatchedDoubleQuotes) {
-  const char kSourceCode[] = "any().\ngo(\"ok\", \"stray quote).break();";
-
-  std::string bytecode;
-  JtlCompiler::CompileError error;
-  EXPECT_FALSE(
-      JtlCompiler::Compile(kSourceCode, kTestHashSeed, &bytecode, &error));
-  EXPECT_EQ(1u, error.line_number);
-  EXPECT_EQ(JtlCompiler::CompileError::MISMATCHED_DOUBLE_QUOTES,
-            error.error_code);
-}
-
-TEST(JtlCompiler, ParsingError) {
-  const char kSourceCode[] = "any().\ngo()missing_separator();";
-
-  std::string bytecode;
-  JtlCompiler::CompileError error;
-  EXPECT_FALSE(
-      JtlCompiler::Compile(kSourceCode, kTestHashSeed, &bytecode, &error));
-  EXPECT_THAT(error.context, testing::base::StartsWith("go"));
-  EXPECT_EQ(1u, error.line_number);
-  EXPECT_EQ(JtlCompiler::CompileError::PARSING_ERROR, error.error_code);
-}
-
-}  // namespace
diff --git a/chrome/tools/profile_reset/jtl_parser.cc b/chrome/tools/profile_reset/jtl_parser.cc
deleted file mode 100644
index c1d9c157..0000000
--- a/chrome/tools/profile_reset/jtl_parser.cc
+++ /dev/null
@@ -1,167 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/tools/profile_reset/jtl_parser.h"
-
-#include <algorithm>
-
-#include "base/logging.h"
-#include "third_party/re2/re2/re2.h"
-
-namespace {
-
-// RegEx that matches the first line of a text. Will throw away any potential
-// double-slash-introduced comments and the potential trailing EOL character.
-// Note: will fail in case the first line contains an unmatched double-quote
-// outside of comments.
-const char kSingleLineWithMaybeCommentsRE[] =
-    // Non-greedily match and capture sequences of 1.) string literals inside
-    // correctly matched double-quotes, or 2.) any other character.
-    "^((?:\"[^\"\\n]*\"|[^\"\\n])*?)"
-    // Greedily match and throw away the potential comment.
-    "(?://.*)?"
-    // Match and throw away EOL, or match end-of-string.
-    "(?:\n|$)";
-
-// RegEx to match either a double-quote-enclosed string literal or a whitespace.
-// Applied repeatedly and without overlapping, can be used to remove whitespace
-// outside of string literals.
-const char kRemoveWhitespaceRE[] = "(\"[^\"]*\")|\\s";
-
-// The substitution pattern to use together with the above when replacing. As
-// the whitespace is not back-referenced here, it will get removed.
-const char kRemoveWhitespaceRewrite[] = "\\1";
-
-// Separator to terminate a sentence.
-const char kEndOfSentenceSeparator[] = ";";
-
-// The 'true' Boolean keyword.
-const char kTrueKeyword[] = "true";
-
-// RegEx that matches and captures one argument, which is either a double-quote
-// enclosed string, or a Boolean value. Will throw away a trailing comma.
-const char kSingleArgumentRE[] = "(?:(?:\"([^\"]*)\"|(true|false))(?:,|$))";
-
-// RegEx-es that, when concatenated, will match a single operation, and capture
-// the: operation name, the optional arguments, and the separator that follows.
-const char kOperationNameRE[] = "([[:word:]]+)";
-const char kMaybeArgumentListRE[] =
-    "(?:\\("                    // Opening parenthesis.
-    "((?:\"[^\"]*\"|[^\")])*)"  // Capture: anything inside, quote-aware.
-    "\\))?";                    // Closing parenthesis + everything optional.
-const char kOperationSeparatorRE[] = "(;|\\.)";
-
-}  // namespace
-
-struct JtlParser::ParsingState {
-  explicit ParsingState(const re2::StringPiece& compacted_source)
-      : single_operation_regex(std::string(kOperationNameRE) +
-                               kMaybeArgumentListRE +
-                               kOperationSeparatorRE),
-        single_argument_regex(kSingleArgumentRE),
-        remaining_compacted_source(compacted_source),
-        last_line_number(0) {}
-
-  RE2 single_operation_regex;
-  RE2 single_argument_regex;
-  re2::StringPiece remaining_compacted_source;
-  re2::StringPiece last_context;
-  size_t last_line_number;
-};
-
-JtlParser::JtlParser(const std::string& compacted_source_code,
-                     const std::vector<size_t>& newline_indices)
-    : compacted_source_(compacted_source_code),
-      newline_indices_(newline_indices) {
-  state_.reset(new ParsingState(compacted_source_));
-}
-
-JtlParser::~JtlParser() {}
-
-// static
-bool JtlParser::RemoveCommentsAndAllWhitespace(
-    const std::string& verbose_text,
-    std::string* compacted_text,
-    std::vector<size_t>* newline_indices,
-    size_t* error_line_number) {
-  DCHECK(compacted_text);
-  DCHECK(newline_indices);
-  std::string line;
-  RE2 single_line_regex(kSingleLineWithMaybeCommentsRE);
-  RE2 remove_whitespace_regex(kRemoveWhitespaceRE);
-  re2::StringPiece verbose_text_piece(verbose_text);
-  compacted_text->clear();
-  newline_indices->clear();
-  while (!verbose_text_piece.empty()) {
-    if (!RE2::Consume(&verbose_text_piece, single_line_regex, &line)) {
-      if (error_line_number)
-        *error_line_number = newline_indices->size();
-      return false;
-    }
-    RE2::GlobalReplace(
-        &line, remove_whitespace_regex, kRemoveWhitespaceRewrite);
-    *compacted_text += line;
-    newline_indices->push_back(compacted_text->size());
-  }
-  return true;
-}
-
-bool JtlParser::HasFinished() {
-  return state_->remaining_compacted_source.empty();
-}
-
-bool JtlParser::ParseNextOperation(std::string* name,
-                                   base::ListValue* argument_list,
-                                   bool* ends_sentence) {
-  DCHECK(name);
-  DCHECK(argument_list);
-  DCHECK(ends_sentence);
-
-  state_->last_context = state_->remaining_compacted_source;
-  state_->last_line_number = GetOriginalLineNumber(
-      compacted_source_.size() - state_->remaining_compacted_source.length());
-
-  std::string arguments, separator;
-  if (!RE2::Consume(&state_->remaining_compacted_source,
-                    state_->single_operation_regex,
-                    name,
-                    &arguments,
-                    &separator))
-    return false;
-
-  *ends_sentence = (separator == kEndOfSentenceSeparator);
-  state_->last_context.remove_suffix(state_->remaining_compacted_source.size());
-
-  re2::StringPiece arguments_piece(arguments);
-  std::string string_value, boolean_value;
-  while (!arguments_piece.empty()) {
-    if (!RE2::Consume(&arguments_piece,
-                      state_->single_argument_regex,
-                      &string_value,
-                      &boolean_value))
-      return false;
-
-    if (!boolean_value.empty()) {
-      argument_list->Append(
-          new base::FundamentalValue(boolean_value == kTrueKeyword));
-    } else {
-      // |string_value| might be empty for an empty string
-      argument_list->Append(new base::StringValue(string_value));
-    }
-  }
-  return true;
-}
-
-size_t JtlParser::GetOriginalLineNumber(size_t compacted_index) const {
-  return static_cast<size_t>(std::upper_bound(newline_indices_.begin(),
-                                              newline_indices_.end(),
-                                              compacted_index) -
-                             newline_indices_.begin());
-}
-
-size_t JtlParser::GetLastLineNumber() const { return state_->last_line_number; }
-
-std::string JtlParser::GetLastContext() const {
-  return state_->last_context.ToString();
-}
diff --git a/chrome/tools/profile_reset/jtl_parser.h b/chrome/tools/profile_reset/jtl_parser.h
deleted file mode 100644
index e758211..0000000
--- a/chrome/tools/profile_reset/jtl_parser.h
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_TOOLS_PROFILE_RESET_JTL_PARSER_H_
-#define CHROME_TOOLS_PROFILE_RESET_JTL_PARSER_H_
-
-#include <string>
-#include <vector>
-
-#include "base/basictypes.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/values.h"
-
-// Parses text-based JTL source code into a stream of operation names, arguments
-// and separator kinds.
-class JtlParser {
- public:
-  // Creates a new parser to parse |compacted_source_code|, which should already
-  // be stripped of all comments and whitespace (except inside string literals).
-  // Use RemoveCommentsAndAllWhitespace() to manufacture these arguments, also
-  // see its comments for a description of |newline_indices|.
-  JtlParser(const std::string& compacted_source_code,
-            const std::vector<size_t>& newline_indices);
-  ~JtlParser();
-
-  // Removes comments from |verbose_text| and compacts it into whitespace-free
-  // format (except inside string literals). Elements in |newline_indices| will
-  // be monotonically increasing and will refer to positions in |compacted_text|
-  // such that a new line has been removed before that position.
-  // Example:
-  //   verbose_text = "H e l l o // my\n"
-  //                  " dear \n"
-  //                  "\n"
-  //                  "world\" ! \""
-  //   compacted_text = "Hellodearworld\" ! \""
-  //                     01234567890123...
-  //   newline_indices = {5, 9, 9}
-  // Returns true on success, false if there were unmatched quotes in a line, in
-  // which case |error_line_number| will be set accordingly if it is non-NULL.
-  static bool RemoveCommentsAndAllWhitespace(
-      const std::string& verbose_text,
-      std::string* compacted_text,
-      std::vector<size_t>* newline_indices,
-      size_t* error_line_number);
-
-  // Returns true if the entire input has been successfully consumed. Note that
-  // even when this returns false, a subsequent call to ParseNextOperation()
-  // might still fail if the next operation cannot be parsed.
-  bool HasFinished();
-
-  // Fetches the |name| and the |argument_list| of the next operation, and also
-  // whether or not it |ends_the_sentence|, i.e. it is followed by the
-  // end-of-sentence separator.
-  // Returns false if there is a parsing error, in which case the values for the
-  // output parameters are undefined, and |this| parser shall no longer be used.
-  bool ParseNextOperation(std::string* name,
-                          base::ListValue* argument_list,
-                          bool* ends_the_sentence);
-
-  // Returns the compacted source code that was passed in to the constructor.
-  const std::string& compacted_source() const { return compacted_source_; }
-
-  // Returns at which line the character at position |compacted_index| in the
-  // |compacted_source()| was originally located.
-  size_t GetOriginalLineNumber(size_t compacted_index) const;
-
-  size_t GetLastLineNumber() const;
-  std::string GetLastContext() const;
-
- private:
-  // Contains pre-compiled regular expressions and related state. Factored out
-  // to avoid this header depending on RE2 headers.
-  struct ParsingState;
-
-  std::string compacted_source_;
-  std::vector<size_t> newline_indices_;
-  scoped_ptr<ParsingState> state_;
-
-  DISALLOW_COPY_AND_ASSIGN(JtlParser);
-};
-
-#endif  // CHROME_TOOLS_PROFILE_RESET_JTL_PARSER_H_
diff --git a/chrome/tools/profile_reset/jtl_parser_unittest.cc b/chrome/tools/profile_reset/jtl_parser_unittest.cc
deleted file mode 100644
index 87b7ebc5..0000000
--- a/chrome/tools/profile_reset/jtl_parser_unittest.cc
+++ /dev/null
@@ -1,346 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/tools/profile_reset/jtl_parser.h"
-
-#include "base/json/json_writer.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/values.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace {
-
-// Helpers -------------------------------------------------------------------
-
-void ExpectNextOperation(JtlParser* parser,
-                         const char* expected_name,
-                         const char* expected_args_json,
-                         bool expected_ends_sentence) {
-  std::string actual_name;
-  base::ListValue actual_args;
-  std::string actual_args_json;
-  bool actual_ends_sentence;
-
-  EXPECT_FALSE(parser->HasFinished());
-  EXPECT_TRUE(parser->ParseNextOperation(
-      &actual_name, &actual_args, &actual_ends_sentence));
-  EXPECT_EQ(expected_name, actual_name);
-  base::JSONWriter::Write(&actual_args, &actual_args_json);
-  EXPECT_EQ(expected_args_json, actual_args_json);
-  EXPECT_EQ(expected_ends_sentence, actual_ends_sentence);
-}
-
-void ExpectNextOperationToFail(JtlParser* parser,
-                               size_t expected_line_number,
-                               const char* expected_context_prefix) {
-  std::string actual_name;
-  base::ListValue actual_args;
-  bool actual_ends_sentence;
-
-  EXPECT_FALSE(parser->HasFinished());
-  EXPECT_FALSE(parser->ParseNextOperation(
-      &actual_name, &actual_args, &actual_ends_sentence));
-  EXPECT_THAT(parser->GetLastContext(),
-              testing::base::StartsWith(expected_context_prefix));
-  EXPECT_EQ(expected_line_number, parser->GetLastLineNumber());
-}
-
-JtlParser* CreateParserFromVerboseText(const std::string& verbose_text) {
-  std::string compacted_source_code;
-  std::vector<size_t> newline_indices;
-  EXPECT_TRUE(JtlParser::RemoveCommentsAndAllWhitespace(
-      verbose_text, &compacted_source_code, &newline_indices, NULL));
-  return new JtlParser(compacted_source_code, newline_indices);
-}
-
-// Tests ---------------------------------------------------------------------
-
-TEST(JtlParser, CompactingEmpty) {
-  const char kSourceCode[] = "";
-  const char kCompactedSourceCode[] = "";
-
-  scoped_ptr<JtlParser> parser(CreateParserFromVerboseText(kSourceCode));
-  EXPECT_EQ(kCompactedSourceCode, parser->compacted_source());
-}
-
-TEST(JtlParser, CompactingTrivial) {
-  const char kSourceCode[] = "foo";
-  const char kCompactedSourceCode[] = "foo";
-
-  scoped_ptr<JtlParser> parser(CreateParserFromVerboseText(kSourceCode));
-  EXPECT_EQ(kCompactedSourceCode, parser->compacted_source());
-}
-
-TEST(JtlParser, CompactingOneLine) {
-  const char kSourceCode[] = "  \r f\to o  ( true )   ";
-  const char kCompactedSourceCode[] = "foo(true)";
-
-  scoped_ptr<JtlParser> parser(CreateParserFromVerboseText(kSourceCode));
-  EXPECT_EQ(kCompactedSourceCode, parser->compacted_source());
-  for (size_t i = 0; i < arraysize(kCompactedSourceCode) - 1; ++i) {
-    SCOPED_TRACE(testing::Message("Position ") << i);
-    EXPECT_EQ(0u, parser->GetOriginalLineNumber(i));
-  }
-}
-
-TEST(JtlParser, CompactingMultipleLines) {
-  const char kSourceCode[] = "a\nbb\n \nccc  \n\n  d( \n e \n )";
-  const char kCompactedSourceCode[] = "abbcccd(e)";
-  const size_t kLineNumbers[] = {0u, 1u, 1u, 3u, 3u, 3u, 5u, 5u, 6u, 7u};
-  static_assert(arraysize(kCompactedSourceCode) == arraysize(kLineNumbers) + 1,
-                "mismatched test data");
-
-  scoped_ptr<JtlParser> parser(CreateParserFromVerboseText(kSourceCode));
-  EXPECT_EQ(kCompactedSourceCode, parser->compacted_source());
-  for (size_t i = 0; i < arraysize(kLineNumbers); ++i) {
-    SCOPED_TRACE(testing::Message("Position ") << i);
-    EXPECT_EQ(kLineNumbers[i], parser->GetOriginalLineNumber(i));
-  }
-}
-
-TEST(JtlParser, CompactingMultipleLinesWithComments) {
-  const char kSourceCode[] =
-      "a/ /b//Comment \n"
-      "//\n"
-      "// Full line comment\n"
-      " cd //";
-  const char kCompactedSourceCode[] = "a//bcd";
-  const size_t kLineNumbers[] = {0u, 0u, 0u, 0u, 3u, 3u};
-  static_assert(arraysize(kCompactedSourceCode) == arraysize(kLineNumbers) + 1,
-                "mismatched test data");
-
-  scoped_ptr<JtlParser> parser(CreateParserFromVerboseText(kSourceCode));
-  EXPECT_EQ(kCompactedSourceCode, parser->compacted_source());
-  for (size_t i = 0; i < arraysize(kLineNumbers); ++i) {
-    SCOPED_TRACE(testing::Message("Position ") << i);
-    EXPECT_EQ(kLineNumbers[i], parser->GetOriginalLineNumber(i));
-  }
-}
-
-TEST(JtlParser, HandlingCommentsAndStringLiterals) {
-  struct TestCase {
-    const char* source_code;
-    const char* compacted_source_code;
-  } cases[] = {
-      {"//", ""},
-      {"//comment", ""},
-      {"foo // comment", "foo"},
-      {"foo // // comment", "foo"},
-      {"foo //", "foo"},
-      {"\"literal\"", "\"literal\""},
-      {"\"literal with space\"", "\"literal with space\""},
-      {"\"\"", "\"\""},
-      {"\"\"\"\"", "\"\"\"\""},
-      {"\"\" // comment", "\"\""},
-      {"\"literal\" // comment", "\"literal\""},
-      {"\"literal\" \"literal\" // comment", "\"literal\"\"literal\""},
-      {"foo // \"not a literal\"", "foo"},
-      {"foo // \"not even matched", "foo"},
-      {"foo // \"not a literal\" \"not even matched", "foo"},
-      {"\"literal\" // \"not a literal\"", "\"literal\""},
-      {"\"literal\" // \"not even matched", "\"literal\""},
-      {"\"//not a comment//\"", "\"//not a comment//\""},
-      {"\"//not a comment//\" // comment", "\"//not a comment//\""},
-      {"// \"//not a literal//\" // comment", ""},
-      {"\"literal\" // \"//not a literal//\" // comment", "\"literal\""},
-      {"\"//not a comment//\" // \"//not a literal//\" // comment",
-       "\"//not a comment//\""},
-      {"\"literal // \"not a literal nor a comment",
-       "\"literal // \"notaliteralnoracomment"},
-      {"\"literal // \"not a literal nor a comment//\"",
-       "\"literal // \"notaliteralnoracomment"}
-  };
-
-  for (size_t i = 0; i < arraysize(cases); ++i) {
-    SCOPED_TRACE(cases[i].source_code);
-    scoped_ptr<JtlParser> parser(
-        CreateParserFromVerboseText(cases[i].source_code));
-    EXPECT_EQ(cases[i].compacted_source_code, parser->compacted_source());
-  }
-}
-
-TEST(JtlParser, MismatchedDoubleQuotesBeforeEndOfLine) {
-  struct TestCase {
-    const char* source_code;
-    size_t error_line_number;
-  } cases[] = {
-      {"\"", 0},
-      {"\"mismatched literal", 0},
-      {"\n\"", 1},
-      {"\"\n\"", 0},
-      {"\"\"\"", 0},
-      {"\"\"\n\"", 1},
-      {"\"\"\n\"\n\"", 1},
-      {"\" // not a comment", 0},
-      {"\" // not a comment\n\"", 0},
-      {"\"\" // comment\n\"", 1},
-      {"\"\"\" // not a comment\n\"", 0},
-      {"\"\"\" // \" neither a literal nor a comment\"\n\"", 0},
-      {"\"\" // comment\n\"// not a comment", 1},
-      {"\" // not a comment\"\n\"// not a comment", 1},
-      {"foo(\"bar\");\nfoo(\"mismatched);", 1},
-      {"foo(\n\"bar\", \"mismatched);", 1},
-      {"foo(\n\"bar\", \"mismatched); //comment", 1},
-      {"foo(\n\"bar\", \"mismatched);\ngood(\"bar\")", 1}
-  };
-
-  for (size_t i = 0; i < arraysize(cases); ++i) {
-    SCOPED_TRACE(cases[i].source_code);
-    std::string compacted_source_code;
-    std::vector<size_t> newline_indices;
-    size_t error_line_number;
-    EXPECT_FALSE(JtlParser::RemoveCommentsAndAllWhitespace(
-        cases[i].source_code,
-        &compacted_source_code,
-        &newline_indices,
-        &error_line_number));
-    EXPECT_EQ(cases[i].error_line_number, error_line_number);
-  }
-}
-
-TEST(JtlParser, ParsingEmpty) {
-  const char kSourceCode[] = "";
-
-  scoped_ptr<JtlParser> parser(CreateParserFromVerboseText(kSourceCode));
-  EXPECT_TRUE(parser->HasFinished());
-}
-
-TEST(JtlParser, ParsingOneWellFormedOperation) {
-  struct TestCase {
-    const char* source_code;
-    const char* expected_name;
-    const char* expected_args;
-    const bool expected_ends_sentence;
-  } cases[] = {
-      {"foo1;", "foo1", "[]", true},
-      {"foo2().", "foo2", "[]", false},
-      {"foo3(true);", "foo3", "[true]", true},
-      {"foo4(false).", "foo4", "[false]", false},
-      {"foo5(\"bar\").", "foo5", "[\"bar\"]", false},
-      {"foo6(\" b a r \").", "foo6", "[\" b a r \"]", false},
-      {"foo7(true, \"bar\").", "foo7", "[true,\"bar\"]", false},
-      {"foo8(\"bar\", false, true);", "foo8", "[\"bar\",false,true]", true},
-      {"foo9(\"bar\", \" b a r \");", "foo9", "[\"bar\",\" b a r \"]", true}
-  };
-
-  for (size_t i = 0; i < arraysize(cases); ++i) {
-    SCOPED_TRACE(cases[i].expected_name);
-    scoped_ptr<JtlParser> parser(
-        CreateParserFromVerboseText(cases[i].source_code));
-    ExpectNextOperation(parser.get(),
-                        cases[i].expected_name,
-                        cases[i].expected_args,
-                        cases[i].expected_ends_sentence);
-    EXPECT_TRUE(parser->HasFinished());
-  }
-}
-
-TEST(JtlParser, ParsingMultipleWellFormedOperations) {
-  const char kSourceCode[] =
-      "foo1(true).foo2.foo3(\"bar\");"
-      "foo4(\"bar\", false);";
-
-  scoped_ptr<JtlParser> parser(CreateParserFromVerboseText(kSourceCode));
-  ExpectNextOperation(parser.get(), "foo1", "[true]", false);
-  ExpectNextOperation(parser.get(), "foo2", "[]", false);
-  ExpectNextOperation(parser.get(), "foo3", "[\"bar\"]", true);
-  ExpectNextOperation(parser.get(), "foo4", "[\"bar\",false]", true);
-  EXPECT_TRUE(parser->HasFinished());
-}
-
-TEST(JtlParser, ParsingTrickyStringLiterals) {
-  struct TestCase {
-    const char* source_code;
-    const char* expected_name;
-    const char* expected_args;
-    const bool expected_ends_sentence;
-  } cases[] = {
-      {"prev().foo1(\"\");next(true);", "foo1", "[\"\"]", true},
-      {"prev().foo2(\" \");next(true);", "foo2", "[\" \"]", true},
-      {"prev().foo3(\",\",true);next(true);", "foo3", "[\",\",true]", true},
-      {"prev().foo4(\")\",true);next(true);", "foo4", "[\")\",true]", true},
-      {"prev().foo5(\";\",true);next(true);", "foo5", "[\";\",true]", true},
-      {"prev().foo6(\"/\",true).next(true);", "foo6", "[\"/\",true]", false},
-      {"prev().foo7(\"//\",true).next(true);", "foo7", "[\"//\",true]", false},
-      {"prev().foo8(\".\",true).next(true);", "foo8", "[\".\",true]", false},
-  };
-
-  for (size_t i = 0; i < arraysize(cases); ++i) {
-    SCOPED_TRACE(cases[i].expected_name);
-    scoped_ptr<JtlParser> parser(
-        CreateParserFromVerboseText(cases[i].source_code));
-    ExpectNextOperation(parser.get(), "prev", "[]", false);
-    ExpectNextOperation(parser.get(),
-                        cases[i].expected_name,
-                        cases[i].expected_args,
-                        cases[i].expected_ends_sentence);
-    ExpectNextOperation(parser.get(), "next", "[true]", true);
-    EXPECT_TRUE(parser->HasFinished());
-  }
-}
-
-TEST(JtlParser, FirstOperationIsIllFormed) {
-  struct TestCase {
-    const char* source_code;
-    const char* operation_name;
-  } cases[] = {
-      {";;", ";"},
-      {"bad_args1(not a boolean value);", "bad_args1"},
-      {"bad_args2(,);", "bad_args2"},
-      {"bad_args3(...);", "bad_args3"},
-      {"bad_args4(1);", "bad_args4"},
-      {"bad_args5(1.2);", "bad_args5"},
-      {"bad_args6([\"bar\"]);", "bad_args6"},
-      {"bad_args7(False);", "bad_args7"},
-      {"bad_args8(True);", "bad_args8"},
-      {"bad_quotes1(missing both, true).good();", "bad_quotes1"},
-      {"bad_quotes2(true, \"missing one).good(); //\"", "bad_quotes2"},
-      {"bad_quotes3(\"too\" \"much\", true).good();", "bad_quotes3"},
-      {"bad_missing_separator1", "bad_missing_separator1"},
-      {"bad_missing_separator2()good();", "bad_missing_separator2"},
-      {"bad_parenthesis1(true.good();", "bad_parenthesis1"},
-      {"bad_parenthesis2(true.good());", "bad_parenthesis2"},
-      {"bad_parenthesis3).good();", "bad_parenthesis3"}
-  };
-
-  for (size_t i = 0; i < arraysize(cases); ++i) {
-    SCOPED_TRACE(cases[i].operation_name);
-    scoped_ptr<JtlParser> parser(
-        CreateParserFromVerboseText(cases[i].source_code));
-    ExpectNextOperationToFail(parser.get(), 0, cases[i].operation_name);
-  }
-}
-
-TEST(JtlParser, SecondOperationIsIllFormed) {
-  struct TestCase {
-    const char* source_code;
-    const char* bad_operation_name;
-  } cases[] = {
-      {"\ngood(true,false)\n.bad_args(,);", "bad_args"},
-      {"\ngood(true,false)\n.bad_quotes1(missing both, true).good();",
-       "bad_quotes1"},
-      {"\ngood(true,false)\n.bad_quotes2(\"missing one, true).good(); //\"",
-       "bad_quotes2"},
-      {"\ngood(true,false)\n.bad_quotes3(\"too\" \"many\", true).good();",
-       "bad_quotes3"},
-      {"\ngood(true,false)\n.bad_separator1()/good();", "bad_separator1"},
-      {"\ngood(true,false)\n.missing_separator1", "missing_separator1"},
-      {"\ngood(true,false)\n.missing_separator2()good();",
-       "missing_separator2"},
-      {"\ngood(true,false)\n.bad_parens1(true.good();", "bad_parens1"},
-      {"\ngood(true,false)\n.bad_parens2(true.good());", "bad_parens2"},
-      {"\ngood(true,false)\n.bad_parens3).good();", "bad_parens3"}
-  };
-
-  for (size_t i = 0; i < arraysize(cases); ++i) {
-    SCOPED_TRACE(cases[i].bad_operation_name);
-    scoped_ptr<JtlParser> parser(
-        CreateParserFromVerboseText(cases[i].source_code));
-    ExpectNextOperation(parser.get(), "good", "[true,false]", false);
-    ExpectNextOperationToFail(parser.get(), 2, cases[i].bad_operation_name);
-  }
-}
-
-}  // namespace
diff --git a/chromeos/network/client_cert_resolver.cc b/chromeos/network/client_cert_resolver.cc
index a0545c989..3d438d88 100644
--- a/chromeos/network/client_cert_resolver.cc
+++ b/chromeos/network/client_cert_resolver.cc
@@ -16,6 +16,7 @@
 #include "base/stl_util.h"
 #include "base/task_runner.h"
 #include "base/threading/worker_pool.h"
+#include "base/time/clock.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/shill_service_client.h"
 #include "chromeos/network/managed_network_configuration_handler.h"
@@ -62,7 +63,8 @@
 
 // Returns true if a private key for certificate |cert| is installed.
 bool HasPrivateKey(const net::X509Certificate& cert) {
-  PK11SlotInfo* slot = PK11_KeyForCertExists(cert.os_cert_handle(), NULL, NULL);
+  PK11SlotInfo* slot =
+      PK11_KeyForCertExists(cert.os_cert_handle(), nullptr, nullptr);
   if (!slot)
     return false;
 
@@ -156,14 +158,15 @@
 }
 
 std::vector<CertAndIssuer> CreateSortedCertAndIssuerList(
-    const net::CertificateList& certs) {
+    const net::CertificateList& certs,
+    base::Time now) {
   // Filter all client certs and determines each certificate's issuer, which is
   // required for the pattern matching.
   std::vector<CertAndIssuer> client_certs;
   for (net::CertificateList::const_iterator it = certs.begin();
        it != certs.end(); ++it) {
     const net::X509Certificate& cert = **it;
-    if (cert.valid_expiry().is_null() || cert.HasExpired() ||
+    if (cert.valid_expiry().is_null() || now > cert.valid_expiry() ||
         !HasPrivateKey(cert) ||
         !CertLoader::IsCertificateHardwareBacked(&cert)) {
       continue;
@@ -180,8 +183,10 @@
 // be run on a worker thread.
 void FindCertificateMatches(const net::CertificateList& certs,
                             std::vector<NetworkAndCertPattern>* networks,
+                            base::Time now,
                             NetworkCertMatches* matches) {
-  std::vector<CertAndIssuer> client_certs(CreateSortedCertAndIssuerList(certs));
+  std::vector<CertAndIssuer> client_certs(
+      CreateSortedCertAndIssuerList(certs, now));
 
   for (std::vector<NetworkAndCertPattern>::const_iterator it =
            networks->begin();
@@ -236,10 +241,10 @@
 ClientCertResolver::ClientCertResolver()
     : resolve_task_running_(false),
       network_properties_changed_(false),
-      network_state_handler_(NULL),
-      managed_network_config_handler_(NULL),
-      weak_ptr_factory_(this) {
-}
+      network_state_handler_(nullptr),
+      managed_network_config_handler_(nullptr),
+      testing_clock_(nullptr),
+      weak_ptr_factory_(this) {}
 
 ClientCertResolver::~ClientCertResolver() {
   if (network_state_handler_)
@@ -287,8 +292,8 @@
     const CertificatePattern& pattern,
     base::DictionaryValue* shill_properties) {
   // Prepare and sort the list of known client certs.
-  std::vector<CertAndIssuer> client_certs(
-      CreateSortedCertAndIssuerList(CertLoader::Get()->cert_list()));
+  std::vector<CertAndIssuer> client_certs(CreateSortedCertAndIssuerList(
+      CertLoader::Get()->cert_list(), base::Time::Now()));
 
   // Search for a certificate matching the pattern.
   std::vector<CertAndIssuer>::iterator cert_it = std::find_if(
@@ -314,6 +319,10 @@
   return true;
 }
 
+void ClientCertResolver::SetClockForTesting(base::Clock* clock) {
+  testing_clock_ = clock;
+}
+
 void ClientCertResolver::NetworkListChanged() {
   VLOG(2) << "NetworkListChanged.";
   if (!ClientCertificatesLoaded())
@@ -346,6 +355,14 @@
   ResolveNetworks(networks_to_check);
 }
 
+void ClientCertResolver::NetworkConnectionStateChanged(
+    const NetworkState* network) {
+  if (!ClientCertificatesLoaded())
+    return;
+  if (!network->IsConnectedState() && !network->IsConnectingState())
+    ResolveNetworks(NetworkStateHandler::NetworkStateList(1, network));
+}
+
 void ClientCertResolver::OnCertificatesLoaded(
     const net::CertificateList& cert_list,
     bool initial_load) {
@@ -448,13 +465,10 @@
   NetworkCertMatches* matches = new NetworkCertMatches;
   task_runner->PostTaskAndReply(
       FROM_HERE,
-      base::Bind(&FindCertificateMatches,
-                 CertLoader::Get()->cert_list(),
-                 base::Owned(networks_to_resolve.release()),
-                 matches),
+      base::Bind(&FindCertificateMatches, CertLoader::Get()->cert_list(),
+                 base::Owned(networks_to_resolve.release()), Now(), matches),
       base::Bind(&ClientCertResolver::ConfigureCertificates,
-                 weak_ptr_factory_.GetWeakPtr(),
-                 base::Owned(matches)));
+                 weak_ptr_factory_.GetWeakPtr(), base::Owned(matches)));
 }
 
 void ClientCertResolver::ResolvePendingNetworks() {
@@ -512,4 +526,10 @@
   FOR_EACH_OBSERVER(Observer, observers_, ResolveRequestCompleted(changed));
 }
 
+base::Time ClientCertResolver::Now() const {
+  if (testing_clock_)
+    return testing_clock_->Now();
+  return base::Time::Now();
+}
+
 }  // namespace chromeos
diff --git a/chromeos/network/client_cert_resolver.h b/chromeos/network/client_cert_resolver.h
index d94873f..931012b 100644
--- a/chromeos/network/client_cert_resolver.h
+++ b/chromeos/network/client_cert_resolver.h
@@ -12,9 +12,9 @@
 #include "base/basictypes.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
+#include "base/time/time.h"
 #include "chromeos/cert_loader.h"
 #include "chromeos/chromeos_export.h"
 #include "chromeos/network/client_cert_util.h"
@@ -23,6 +23,7 @@
 #include "chromeos/network/network_state_handler_observer.h"
 
 namespace base {
+class Clock;
 class TaskRunner;
 }
 
@@ -74,10 +75,16 @@
   // |Observer|.
   bool IsAnyResolveTaskRunning() const;
 
+  // Sets the clock for testing. This clock is used when checking the
+  // certificates for expiration.
+  void SetClockForTesting(base::Clock* clock);
+
   // Returns true and sets the Shill properties that have to be configured in
   // |shill_properties| if the certificate pattern |pattern| could be resolved.
   // Returns false otherwise and sets empty Shill properties to clear the
   // certificate configuration.
+  // Note that it uses the global clock when checking the certificates for
+  // expiration.
   static bool ResolveCertificatePatternSync(
       const client_cert::ConfigType client_cert_type,
       const CertificatePattern& pattern,
@@ -86,6 +93,7 @@
  private:
   // NetworkStateHandlerObserver overrides
   void NetworkListChanged() override;
+  void NetworkConnectionStateChanged(const NetworkState* network) override;
 
   // CertLoader::Observer overrides
   void OnCertificatesLoaded(const net::CertificateList& cert_list,
@@ -110,6 +118,11 @@
   // Trigger a ResolveRequestCompleted event on all observers.
   void NotifyResolveRequestCompleted();
 
+  // Returns Time::Now() unless a mock clock has been installed with
+  // SetClockForTesting, in which case the time according to that clock is used
+  // instead.
+  base::Time Now() const;
+
   base::ObserverList<Observer> observers_;
 
   // The set of networks that were checked/resolved in previous passes. These
@@ -135,6 +148,9 @@
   // TaskRunner for slow tasks.
   scoped_refptr<base::TaskRunner> slow_task_runner_for_test_;
 
+  // Can be set for testing.
+  base::Clock* testing_clock_;
+
   base::WeakPtrFactory<ClientCertResolver> weak_ptr_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(ClientCertResolver);
diff --git a/chromeos/network/client_cert_resolver_unittest.cc b/chromeos/network/client_cert_resolver_unittest.cc
index 7f2035b..4006072 100644
--- a/chromeos/network/client_cert_resolver_unittest.cc
+++ b/chromeos/network/client_cert_resolver_unittest.cc
@@ -11,8 +11,10 @@
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/json/json_reader.h"
+#include "base/memory/scoped_ptr.h"
 #include "base/run_loop.h"
 #include "base/strings/stringprintf.h"
+#include "base/test/simple_test_clock.h"
 #include "base/values.h"
 #include "chromeos/cert_loader.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
@@ -50,9 +52,9 @@
  public:
   ClientCertResolverTest()
       : network_properties_changed_count_(0),
-        service_test_(NULL),
-        profile_test_(NULL),
-        cert_loader_(NULL) {}
+        service_test_(nullptr),
+        profile_test_(nullptr),
+        cert_loader_(nullptr) {}
   ~ClientCertResolverTest() override {}
 
   void SetUp() override {
@@ -82,6 +84,7 @@
   void TearDown() override {
     client_cert_resolver_->RemoveObserver(this);
     client_cert_resolver_.reset();
+    test_clock_.reset();
     managed_config_handler_.reset();
     network_config_handler_.reset();
     network_profile_handler_.reset();
@@ -138,6 +141,10 @@
     managed_config_handler_.reset(new ManagedNetworkConfigurationHandlerImpl());
     client_cert_resolver_.reset(new ClientCertResolver());
 
+    test_clock_.reset(new base::SimpleTestClock);
+    test_clock_->SetNow(base::Time::Now());
+    client_cert_resolver_->SetClockForTesting(test_clock_.get());
+
     network_profile_handler_->Init();
     network_config_handler_->Init(network_state_handler_.get(),
                                   nullptr /* network_device_handler */);
@@ -198,10 +205,10 @@
 
     std::string error;
     scoped_ptr<base::Value> policy_value = base::JSONReader::ReadAndReturnError(
-        kTestPolicy, base::JSON_ALLOW_TRAILING_COMMAS, NULL, &error);
+        kTestPolicy, base::JSON_ALLOW_TRAILING_COMMAS, nullptr, &error);
     ASSERT_TRUE(policy_value) << error;
 
-    base::ListValue* policy = NULL;
+    base::ListValue* policy = nullptr;
     ASSERT_TRUE(policy_value->GetAsList(&policy));
 
     managed_config_handler_->SetPolicy(
@@ -234,10 +241,10 @@
 
     std::string error;
     scoped_ptr<base::Value> policy_value = base::JSONReader::ReadAndReturnError(
-        policy_json, base::JSON_ALLOW_TRAILING_COMMAS, NULL, &error);
+        policy_json, base::JSON_ALLOW_TRAILING_COMMAS, nullptr, &error);
     ASSERT_TRUE(policy_value) << error;
 
-    base::ListValue* policy = NULL;
+    base::ListValue* policy = nullptr;
     ASSERT_TRUE(policy_value->GetAsList(&policy));
 
     managed_config_handler_->SetPolicy(
@@ -247,6 +254,11 @@
         base::DictionaryValue() /* no global network config */);
   }
 
+  void SetWifiState(const std::string& state) {
+    ASSERT_TRUE(service_test_->SetServiceProperty(
+        kWifiStub, shill::kStateProperty, base::StringValue(state)));
+  }
+
   void GetClientCertProperties(std::string* pkcs11_id) {
     pkcs11_id->clear();
     const base::DictionaryValue* properties =
@@ -259,6 +271,7 @@
 
   int network_properties_changed_count_;
   std::string test_cert_id_;
+  scoped_ptr<base::SimpleTestClock> test_clock_;
   scoped_ptr<ClientCertResolver> client_cert_resolver_;
 
  private:
@@ -365,4 +378,34 @@
   EXPECT_EQ(1, network_properties_changed_count_);
 }
 
+TEST_F(ClientCertResolverTest, ExpiringCertificate) {
+  SetupTestCerts(true /* import issuer */);
+  SetupWifi();
+  base::RunLoop().RunUntilIdle();
+
+  SetupNetworkHandlers();
+  SetupPolicyMatchingIssuerPEM();
+  base::RunLoop().RunUntilIdle();
+
+  StartCertLoader();
+  base::RunLoop().RunUntilIdle();
+
+  SetWifiState(shill::kStateOnline);
+  base::RunLoop().RunUntilIdle();
+
+  // Verify that the resolver positively matched the pattern in the policy with
+  // the test client cert and configured the network.
+  std::string pkcs11_id;
+  GetClientCertProperties(&pkcs11_id);
+  EXPECT_EQ(test_cert_id_, pkcs11_id);
+
+  // Verify that, after the certificate expired and the network disconnection
+  // happens, no client certificate was configured.
+  test_clock_->SetNow(base::Time::Max());
+  SetWifiState(shill::kStateOffline);
+  base::RunLoop().RunUntilIdle();
+  GetClientCertProperties(&pkcs11_id);
+  EXPECT_EQ(std::string(), pkcs11_id);
+}
+
 }  // namespace chromeos
diff --git a/chromeos/settings/cros_settings_names.cc b/chromeos/settings/cros_settings_names.cc
index d9be0eb..f6de5ca 100644
--- a/chromeos/settings/cros_settings_names.cc
+++ b/chromeos/settings/cros_settings_names.cc
@@ -175,4 +175,12 @@
 // size in bytes.
 const char kExtensionCacheSize[] = "cros.device.extension_cache_size";
 
+// An integer pref that sets the display rotation at startup to a certain
+// value, overriding the user value:
+// 0 = 0 degrees rotation
+// 1 = 90 degrees clockwise rotation
+// 2 = 180 degrees rotation
+// 3 = 270 degrees clockwise rotation
+const char kDisplayRotationDefault[] = "cros.display_rotation_default";
+
 }  // namespace chromeos
diff --git a/chromeos/settings/cros_settings_names.h b/chromeos/settings/cros_settings_names.h
index c2411518..2045b9e 100644
--- a/chromeos/settings/cros_settings_names.h
+++ b/chromeos/settings/cros_settings_names.h
@@ -92,6 +92,8 @@
 
 CHROMEOS_EXPORT extern const char kExtensionCacheSize[];
 
+CHROMEOS_EXPORT extern const char kDisplayRotationDefault[];
+
 }  // namespace chromeos
 
 #endif  // CHROMEOS_SETTINGS_CROS_SETTINGS_NAMES_H_
diff --git a/components/BUILD.gn b/components/BUILD.gn
index 8da3a158..79e21283 100644
--- a/components/BUILD.gn
+++ b/components/BUILD.gn
@@ -36,6 +36,9 @@
     "//components/device_event_log",
     "//components/dom_distiller/core",
     "//components/google/core/browser",
+    "//components/history/core/browser",
+    "//components/history/core/common",
+    "//components/history/core/test",
     "//components/keyed_service/core",
     "//components/password_manager/core/browser",
     "//components/password_manager/core/common",
@@ -50,6 +53,8 @@
     "//components/pref_registry",
     "//components/omnibox/browser",
     "//components/infobars/core",
+    "//components/translate/core/browser",
+    "//components/translate/core/common",
     "//components/version_ui",
     "//components/os_crypt",
   ]
@@ -92,9 +97,6 @@
       "//components/gcm_driver/crypto",
       "//components/gcm_driver/instance_id",
       "//components/history/content/browser",
-      "//components/history/core/browser",
-      "//components/history/core/common",
-      "//components/history/core/test",
       "//components/invalidation/impl",
       "//components/json_schema",
       "//components/keyed_service/content",
@@ -142,8 +144,6 @@
       "//components/translate/content/browser",
       "//components/translate/content/common",
       "//components/translate/content/renderer",
-      "//components/translate/core/browser",
-      "//components/translate/core/common",
       "//components/ui/zoom",
       "//components/update_client",
       "//components/upload_list",
@@ -226,7 +226,9 @@
     deps += [
       "//components/autofill/ios/browser",
       "//components/dom_distiller/ios",
+      "//components/history/ios/browser",
       "//components/keyed_service/ios",
+      "//components/translate/ios/browser",
       "//components/webp_transcode",
     ]
   }
@@ -337,6 +339,8 @@
     "//components/data_usage/core:unit_tests",
     "//components/dom_distiller/core:unit_tests",
     "//components/google/core/browser:unit_tests",
+    "//components/history/core/browser:unit_tests",
+    "//components/history/core/common:unit_tests",
     "//components/keyed_service/core:unit_tests",
     "//components/net_log:unit_tests",
     "//components/password_manager/core/browser:unit_tests",
@@ -353,6 +357,9 @@
     "//components/undo:unit_tests",
     "//components/leveldb_proto:unit_tests",
     "//components/suggestions:unit_tests",
+    "//components/translate/core/browser:unit_tests",
+    "//components/translate/core/common:unit_tests",
+    "//components/translate/core/language_detection:unit_tests",
     "//components/omnibox/browser:unit_tests",
     "//components/os_crypt:unit_tests",
   ]
@@ -400,8 +407,6 @@
       "//components/gcm_driver/instance_id:unit_tests",
       "//components/gcm_driver:unit_tests",
       "//components/history/content/browser:unit_tests",
-      "//components/history/core/browser:unit_tests",
-      "//components/history/core/common:unit_tests",
       "//components/invalidation/impl:unit_tests",
       "//components/json_schema:unit_tests",
       "//components/keyed_service/content:unit_tests",
@@ -429,9 +434,6 @@
       "//components/sync_bookmarks:unit_tests",
       "//components/sync_driver:unit_tests",
       "//components/sync_sessions:unit_tests",
-      "//components/translate/core/browser:unit_tests",
-      "//components/translate/core/common:unit_tests",
-      "//components/translate/core/language_detection:unit_tests",
       "//components/url_formatter:unit_tests",
       "//components/url_matcher:unit_tests",
       "//components/update_client:unit_tests",
@@ -504,7 +506,10 @@
       ]
     }
   } else {
-    deps += [ "//components/webp_transcode:unit_tests" ]
+    deps += [
+      "//components/translate/ios/browser:unit_tests",
+      "//components/webp_transcode:unit_tests",
+    ]
   }
 
   if (toolkit_views) {
diff --git a/components/autofill.gypi b/components/autofill.gypi
index 2eb1617..e494a094 100644
--- a/components/autofill.gypi
+++ b/components/autofill.gypi
@@ -80,6 +80,7 @@
         '../third_party/libjingle/libjingle.gyp:libjingle',
         '../third_party/libaddressinput/libaddressinput.gyp:libaddressinput_util',
         '../third_party/libphonenumber/libphonenumber.gyp:libphonenumber',
+        '../third_party/re2/re2.gyp:re2',
         '../ui/base/ui_base.gyp:ui_base',
         '../ui/gfx/gfx.gyp:gfx',
         '../ui/gfx/gfx.gyp:gfx_geometry',
diff --git a/components/autofill/content/renderer/password_autofill_agent.cc b/components/autofill/content/renderer/password_autofill_agent.cc
index 845e52c..4247b5f1 100644
--- a/components/autofill/content/renderer/password_autofill_agent.cc
+++ b/components/autofill/content/renderer/password_autofill_agent.cc
@@ -1348,7 +1348,7 @@
 
 void PasswordAutofillAgent::OnAutofillUsernameAndPasswordDataReceived(
     const FormsPredictionsMap& predictions) {
-  form_predictions_ = predictions;
+  form_predictions_.insert(predictions.begin(), predictions.end());
 }
 
 void PasswordAutofillAgent::OnFindFocusedPasswordForm() {
diff --git a/components/autofill/core/browser/BUILD.gn b/components/autofill/core/browser/BUILD.gn
index d946f1e..73c5cb3 100644
--- a/components/autofill/core/browser/BUILD.gn
+++ b/components/autofill/core/browser/BUILD.gn
@@ -157,6 +157,7 @@
     "//base",
     "//base:i18n",
     "//base:prefs",
+    "//third_party/re2",
     "//components/autofill/core/common",
     "//components/compression",
     "//components/data_use_measurement/core",
diff --git a/components/autofill/core/browser/DEPS b/components/autofill/core/browser/DEPS
index 1aaa249..164b1d9a 100644
--- a/components/autofill/core/browser/DEPS
+++ b/components/autofill/core/browser/DEPS
@@ -19,6 +19,7 @@
   "+third_party/webrtc/libjingle",
   "+third_party/libaddressinput", # For address i18n.
   "+third_party/libphonenumber",  # For phone number i18n.
+  "+third_party/re2",
   "+ui/base",
   "+ui/gfx",
 ]
diff --git a/components/autofill/core/browser/autofill_download_manager.cc b/components/autofill/core/browser/autofill_download_manager.cc
index 4f2a391..7676d1e 100644
--- a/components/autofill/core/browser/autofill_download_manager.cc
+++ b/components/autofill/core/browser/autofill_download_manager.cc
@@ -65,6 +65,7 @@
 
 struct AutofillDownloadManager::FormRequestData {
   std::vector<std::string> form_signatures;
+  std::vector<FormStructure*> queried_forms;
   RequestType request_type;
 };
 
@@ -107,6 +108,7 @@
   std::string form_xml;
   FormRequestData request_data;
   if (!FormStructure::EncodeQueryRequest(forms, &request_data.form_signatures,
+                                         &request_data.queried_forms,
                                          &form_xml)) {
     return false;
   }
@@ -119,7 +121,8 @@
     VLOG(1) << "AutofillDownloadManager: query request has been retrieved "
              << "from the cache, form signatures: "
              << GetCombinedSignature(request_data.form_signatures);
-    observer_->OnLoadedServerPredictions(query_data);
+    observer_->OnLoadedServerPredictions(query_data,
+                                         request_data.queried_forms);
     return true;
   }
 
@@ -341,7 +344,8 @@
              << " request has succeeded with response body: " << response_body;
     if (it->second.request_type == AutofillDownloadManager::REQUEST_QUERY) {
       CacheQueryRequest(it->second.form_signatures, response_body);
-      observer_->OnLoadedServerPredictions(response_body);
+      observer_->OnLoadedServerPredictions(response_body,
+                                           it->second.queried_forms);
     } else {
       double new_positive_upload_rate = 0;
       double new_negative_upload_rate = 0;
diff --git a/components/autofill/core/browser/autofill_download_manager.h b/components/autofill/core/browser/autofill_download_manager.h
index e1c8b9ff..86d9a55 100644
--- a/components/autofill/core/browser/autofill_download_manager.h
+++ b/components/autofill/core/browser/autofill_download_manager.h
@@ -38,8 +38,11 @@
   class Observer {
    public:
     // Called when field type predictions are successfully received from the
-    // server.  |response_xml| contains the server response.
-    virtual void OnLoadedServerPredictions(const std::string& response_xml) = 0;
+    // server. |response_xml| contains the server response for the
+    // |queried_forms|.
+    virtual void OnLoadedServerPredictions(
+        const std::string& response_xml,
+        const std::vector<FormStructure*>& queried_forms) = 0;
 
     // These notifications are used to help with testing.
     // Called when heuristic either successfully considered for upload and
diff --git a/components/autofill/core/browser/autofill_download_manager_unittest.cc b/components/autofill/core/browser/autofill_download_manager_unittest.cc
index 042aba1..8562863c 100644
--- a/components/autofill/core/browser/autofill_download_manager_unittest.cc
+++ b/components/autofill/core/browser/autofill_download_manager_unittest.cc
@@ -80,7 +80,9 @@
   }
 
   // AutofillDownloadManager::Observer implementation.
-  void OnLoadedServerPredictions(const std::string& response_xml) override {
+  void OnLoadedServerPredictions(
+      const std::string& response_xml,
+      const std::vector<FormStructure*>& queried_forms) override {
     ResponseData response;
     response.response = response_xml;
     response.type_of_response = QUERY_SUCCESSFULL;
diff --git a/components/autofill/core/browser/autofill_manager.cc b/components/autofill/core/browser/autofill_manager.cc
index 3dd5d07f..031691e 100644
--- a/components/autofill/core/browser/autofill_manager.cc
+++ b/components/autofill/core/browser/autofill_manager.cc
@@ -741,17 +741,18 @@
 }
 
 void AutofillManager::OnLoadedServerPredictions(
-    const std::string& response_xml) {
+    const std::string& response_xml,
+    const std::vector<FormStructure*>& queried_forms) {
   // Parse and store the server predictions.
-  FormStructure::ParseQueryResponse(response_xml, form_structures_.get(),
+  FormStructure::ParseQueryResponse(response_xml, queried_forms,
                                     client_->GetRapporService());
 
   // Forward form structures to the password generation manager to detect
   // account creation forms.
-  driver_->PropagateAutofillPredictions(form_structures_.get());
+  driver_->PropagateAutofillPredictions(queried_forms);
 
   // If the corresponding flag is set, annotate forms with the predicted types.
-  driver_->SendAutofillTypePredictionsToRenderer(form_structures_.get());
+  driver_->SendAutofillTypePredictionsToRenderer(queried_forms);
 }
 
 void AutofillManager::OnUnmaskResponse(const UnmaskResponse& response) {
diff --git a/components/autofill/core/browser/autofill_manager.h b/components/autofill/core/browser/autofill_manager.h
index 56dfad4..f1ab96d89 100644
--- a/components/autofill/core/browser/autofill_manager.h
+++ b/components/autofill/core/browser/autofill_manager.h
@@ -246,7 +246,9 @@
 
  private:
   // AutofillDownloadManager::Observer:
-  void OnLoadedServerPredictions(const std::string& response_xml) override;
+  void OnLoadedServerPredictions(
+      const std::string& response_xml,
+      const std::vector<FormStructure*>& queried_forms) override;
 
   // CardUnmaskDelegate:
   void OnUnmaskResponse(const UnmaskResponse& response) override;
diff --git a/components/autofill/core/browser/form_structure.cc b/components/autofill/core/browser/form_structure.cc
index 590abf4..16a6c34 100644
--- a/components/autofill/core/browser/form_structure.cc
+++ b/components/autofill/core/browser/form_structure.cc
@@ -31,7 +31,7 @@
 #include "components/autofill/core/common/form_field_data_predictions.h"
 #include "components/rappor/rappor_service.h"
 #include "components/rappor/rappor_utils.h"
-#include "third_party/icu/source/i18n/unicode/regex.h"
+#include "third_party/re2/re2/re2.h"
 #include "third_party/webrtc/libjingle/xmllite/xmlelement.h"
 
 namespace autofill {
@@ -65,7 +65,7 @@
 const char kShippingMode[] = "shipping";
 
 // Strip away >= 5 consecutive digits.
-const char kIgnorePatternInFieldName[] = "\\d{5,}+";
+const char kIgnorePatternInFieldName[] = "\\d{5,}";
 
 // A form is considered to have a high prediction mismatch rate if the number of
 // mismatches exceeds this threshold.
@@ -356,28 +356,10 @@
 }
 
 std::string StripDigitsIfRequired(const base::string16& input) {
-  UErrorCode status = U_ZERO_ERROR;
-  CR_DEFINE_STATIC_LOCAL(icu::UnicodeString, icu_pattern,
-                         (kIgnorePatternInFieldName));
-  CR_DEFINE_STATIC_LOCAL(icu::RegexMatcher, matcher,
-                         (icu_pattern, UREGEX_CASE_INSENSITIVE, status));
-  DCHECK_EQ(status, U_ZERO_ERROR);
+  std::string return_string = base::UTF16ToUTF8(input);
 
-  icu::UnicodeString icu_input(input.data(), input.length());
-  matcher.reset(icu_input);
-
-  icu::UnicodeString replaced_string = matcher.replaceAll("", status);
-
-  std::string return_string;
-  status = U_ZERO_ERROR;
-  base::UTF16ToUTF8(replaced_string.getBuffer(),
-                    static_cast<size_t>(replaced_string.length()),
-                    &return_string);
-  if (status != U_ZERO_ERROR) {
-    DVLOG(1) << "Couldn't strip digits in " << base::UTF16ToUTF8(input);
-    return base::UTF16ToUTF8(input);
-  }
-
+  re2::RE2::GlobalReplace(&return_string, re2::RE2(kIgnorePatternInFieldName),
+                          std::string());
   return return_string;
 }
 
@@ -535,12 +517,15 @@
 bool FormStructure::EncodeQueryRequest(
     const std::vector<FormStructure*>& forms,
     std::vector<std::string>* encoded_signatures,
+    std::vector<FormStructure*>* queried_forms,
     std::string* encoded_xml) {
   DCHECK(encoded_signatures);
   DCHECK(encoded_xml);
   encoded_xml->clear();
   encoded_signatures->clear();
   encoded_signatures->reserve(forms.size());
+  queried_forms->clear();
+  queried_forms->reserve(forms.size());
 
   // Set up the <autofillquery> element and attributes.
   buzz::XmlElement autofill_request_xml(
@@ -568,6 +553,7 @@
 
     autofill_request_xml.AddElement(encompassing_xml_element.release());
     encoded_signatures->push_back(signature);
+    queried_forms->push_back(it);
   }
 
   if (!encoded_signatures->size())
diff --git a/components/autofill/core/browser/form_structure.h b/components/autofill/core/browser/form_structure.h
index 786485e..14cdd1da 100644
--- a/components/autofill/core/browser/form_structure.h
+++ b/components/autofill/core/browser/form_structure.h
@@ -69,13 +69,17 @@
   bool EncodeFieldAssignments(const ServerFieldTypeSet& available_field_types,
                               std::string* encoded_xml) const;
 
-  // Encodes the XML query request for the set of forms.
-  // All fields are returned in one XML. For example, there are three forms,
+  // Encodes the XML query request for the set of |forms| that are valid (see
+  // implementation for details on which forms are not included in the query).
+  // The forms and form signatures used in the Query request are output in
+  // |queried_forms| and |encoded_signatures|, respectively. All valid fields
+  // are encoded in |encoded_xml|. For example, there are three valid forms,
   // with 2, 4, and 3 fields. The returned XML would have type info for 9
   // fields, first two of which would be for the first form, next 4 for the
   // second, and the rest is for the third.
   static bool EncodeQueryRequest(const std::vector<FormStructure*>& forms,
                                  std::vector<std::string>* encoded_signatures,
+                                 std::vector<FormStructure*>* queried_forms,
                                  std::string* encoded_xml);
 
   // Parses the field types from the server query response. |forms| must be the
diff --git a/components/autofill/core/browser/form_structure_unittest.cc b/components/autofill/core/browser/form_structure_unittest.cc
index 5a0cb53..2b63178d 100644
--- a/components/autofill/core/browser/form_structure_unittest.cc
+++ b/components/autofill/core/browser/form_structure_unittest.cc
@@ -1483,6 +1483,7 @@
   ScopedVector<FormStructure> forms;
   forms.push_back(new FormStructure(form));
   std::vector<std::string> encoded_signatures;
+  std::vector<FormStructure*> queried_forms;
   std::string encoded_xml;
   const char kSignature1[] = "11337937696949187602";
   const char kResponse1[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
@@ -1496,21 +1497,22 @@
       " name=\"expiration_month\" type=\"text\" label=\"Expiration Date\"/>"
       "<field signature=\"4108155786\" name=\"expiration_year\" type=\"text\""
       " label=\"Expiration Year\"/></form></autofillquery>";
-  ASSERT_TRUE(FormStructure::EncodeQueryRequest(forms.get(),
-                                                &encoded_signatures,
-                                                &encoded_xml));
+  ASSERT_TRUE(FormStructure::EncodeQueryRequest(
+      forms.get(), &encoded_signatures, &queried_forms, &encoded_xml));
   ASSERT_EQ(1U, encoded_signatures.size());
   EXPECT_EQ(kSignature1, encoded_signatures[0]);
+  EXPECT_EQ(forms[0], queried_forms[0]);
   EXPECT_EQ(kResponse1, encoded_xml);
 
   // Add the same form, only one will be encoded, so EncodeQueryRequest() should
   // return the same data.
   forms.push_back(new FormStructure(form));
-  ASSERT_TRUE(FormStructure::EncodeQueryRequest(forms.get(),
-                                                &encoded_signatures,
-                                                &encoded_xml));
+  ASSERT_TRUE(FormStructure::EncodeQueryRequest(
+      forms.get(), &encoded_signatures, &queried_forms, &encoded_xml));
   ASSERT_EQ(1U, encoded_signatures.size());
   EXPECT_EQ(kSignature1, encoded_signatures[0]);
+  ASSERT_EQ(1U, queried_forms.size());
+  EXPECT_EQ(forms[0], queried_forms[0]);
   EXPECT_EQ(kResponse1, encoded_xml);
   // Add 5 address fields - this should be still a valid form.
   for (size_t i = 0; i < 5; ++i) {
@@ -1520,9 +1522,8 @@
   }
 
   forms.push_back(new FormStructure(form));
-  ASSERT_TRUE(FormStructure::EncodeQueryRequest(forms.get(),
-                                                &encoded_signatures,
-                                                &encoded_xml));
+  ASSERT_TRUE(FormStructure::EncodeQueryRequest(
+      forms.get(), &encoded_signatures, &queried_forms, &encoded_xml));
   ASSERT_EQ(2U, encoded_signatures.size());
   EXPECT_EQ(kSignature1, encoded_signatures[0]);
   const char kSignature2[] = "8308881815906226214";
@@ -1565,21 +1566,23 @@
   }
 
   forms.push_back(new FormStructure(malformed_form));
-  ASSERT_TRUE(FormStructure::EncodeQueryRequest(forms.get(),
-                                                &encoded_signatures,
-                                                &encoded_xml));
+  ASSERT_TRUE(FormStructure::EncodeQueryRequest(
+      forms.get(), &encoded_signatures, &queried_forms, &encoded_xml));
   ASSERT_EQ(2U, encoded_signatures.size());
   EXPECT_EQ(kSignature1, encoded_signatures[0]);
   EXPECT_EQ(kSignature2, encoded_signatures[1]);
+  ASSERT_EQ(2U, queried_forms.size());
+  EXPECT_EQ(forms[0], queried_forms[0]);
+  EXPECT_EQ(forms[2], queried_forms[1]);
   EXPECT_EQ(kResponse2, encoded_xml);
 
   // Check that we fail if there are only bad form(s).
   ScopedVector<FormStructure> bad_forms;
   bad_forms.push_back(new FormStructure(malformed_form));
-  EXPECT_FALSE(FormStructure::EncodeQueryRequest(bad_forms.get(),
-                                                 &encoded_signatures,
-                                                 &encoded_xml));
+  EXPECT_FALSE(FormStructure::EncodeQueryRequest(
+      bad_forms.get(), &encoded_signatures, &queried_forms, &encoded_xml));
   EXPECT_EQ(0U, encoded_signatures.size());
+  EXPECT_EQ(0U, queried_forms.size());
   EXPECT_EQ("", encoded_xml);
 }
 
@@ -2766,6 +2769,7 @@
   ScopedVector<FormStructure> forms;
   forms.push_back(new FormStructure(form));
   std::vector<std::string> encoded_signatures;
+  std::vector<FormStructure*> queried_forms;
   std::string encoded_xml;
 
   const char kSignature[] = "18006745212084723782";
@@ -2776,11 +2780,11 @@
       " label=\"username\"/>"
       "<field signature=\"420638584\" name=\"email\" type=\"text\"/>"
       "</form></autofillquery>";
-  ASSERT_TRUE(FormStructure::EncodeQueryRequest(forms.get(),
-                                                &encoded_signatures,
-                                                &encoded_xml));
+  ASSERT_TRUE(FormStructure::EncodeQueryRequest(
+      forms.get(), &encoded_signatures, &queried_forms, &encoded_xml));
   ASSERT_EQ(1U, encoded_signatures.size());
   EXPECT_EQ(kSignature, encoded_signatures[0]);
+  EXPECT_EQ(forms[0], queried_forms[0]);
   EXPECT_EQ(kResponse, encoded_xml);
 }
 
@@ -2809,6 +2813,7 @@
   ScopedVector<FormStructure> forms;
   forms.push_back(new FormStructure(form));
   std::vector<std::string> encoded_signatures;
+  std::vector<FormStructure*> queried_forms;
   std::string encoded_xml;
 
   const char kRequest[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
@@ -2819,9 +2824,8 @@
       " label=\"Enter your Email address\"/>"
       "<field signature=\"2051817934\" name=\"password\" type=\"password\""
       " label=\"Enter your Password\"/></form></autofillquery>";
-  EXPECT_TRUE(FormStructure::EncodeQueryRequest(forms.get(),
-                                                &encoded_signatures,
-                                                &encoded_xml));
+  EXPECT_TRUE(FormStructure::EncodeQueryRequest(
+      forms.get(), &encoded_signatures, &queried_forms, &encoded_xml));
   EXPECT_EQ(kRequest, encoded_xml);
 }
 
@@ -2855,6 +2859,7 @@
   ScopedVector<FormStructure> forms;
   forms.push_back(new FormStructure(form));
   std::vector<std::string> encoded_signatures;
+  std::vector<FormStructure*> queried_forms;
   std::string encoded_xml;
 
   const char kRequest[] =
@@ -2870,7 +2875,7 @@
       "<field signature=\"2051817934\" name=\"password\" type=\"password\""
       " label=\"Enter your Password\"/></form></autofillquery>";
   EXPECT_TRUE(FormStructure::EncodeQueryRequest(
-      forms.get(), &encoded_signatures, &encoded_xml));
+      forms.get(), &encoded_signatures, &queried_forms, &encoded_xml));
   EXPECT_EQ(kRequest, encoded_xml);
 }
 
@@ -2897,6 +2902,7 @@
   ScopedVector<FormStructure> forms;
   forms.push_back(new FormStructure(form));
   std::vector<std::string> encoded_signatures;
+  std::vector<FormStructure*> queried_forms;
   std::string encoded_xml;
 
   const char kSignature[] = "16416961345885087496";
@@ -2906,11 +2912,11 @@
       "<field signature=\"239111655\" name=\"username\" type=\"text\""
       " label=\"username\"/><field signature=\"1318412689\" type=\"text\"/>"
       "</form></autofillquery>";
-  ASSERT_TRUE(FormStructure::EncodeQueryRequest(forms.get(),
-                                                &encoded_signatures,
-                                                &encoded_xml));
+  ASSERT_TRUE(FormStructure::EncodeQueryRequest(
+      forms.get(), &encoded_signatures, &queried_forms, &encoded_xml));
   ASSERT_EQ(1U, encoded_signatures.size());
   EXPECT_EQ(kSignature, encoded_signatures[0]);
+  EXPECT_EQ(forms[0], queried_forms[0]);
   EXPECT_EQ(kResponse, encoded_xml);
 }
 
@@ -2938,6 +2944,7 @@
   ScopedVector<FormStructure> forms;
   forms.push_back(new FormStructure(form));
   std::vector<std::string> encoded_signatures;
+  std::vector<FormStructure*> queried_forms;
   std::string encoded_xml;
 
   const char kSignature[] = "7635954436925888745";
@@ -2947,11 +2954,11 @@
       "<field signature=\"239111655\"/>"
       "<field signature=\"3654076265\"/>"
       "</form></autofillquery>";
-  ASSERT_TRUE(FormStructure::EncodeQueryRequest(forms.get(),
-                                                &encoded_signatures,
-                                                &encoded_xml));
+  ASSERT_TRUE(FormStructure::EncodeQueryRequest(
+      forms.get(), &encoded_signatures, &queried_forms, &encoded_xml));
   ASSERT_EQ(1U, encoded_signatures.size());
   EXPECT_EQ(kSignature, encoded_signatures[0]);
+  EXPECT_EQ(forms[0], queried_forms[0]);
   EXPECT_EQ(kResponse, encoded_xml);
 }
 
diff --git a/components/components_tests.gyp b/components/components_tests.gyp
index c93831b..fd49988 100644
--- a/components/components_tests.gyp
+++ b/components/components_tests.gyp
@@ -732,7 +732,6 @@
       'translate/core/common/translate_metrics_unittest.cc',
       'translate/core/common/translate_util_unittest.cc',
       'translate/core/language_detection/language_detection_util_unittest.cc',
-      # TODO(GYP) bug 523060: these translate tests on iOS.
       'translate/ios/browser/js_translate_manager_unittest.mm',
       'translate/ios/browser/language_detection_controller_unittest.mm',
       'translate/ios/browser/translate_controller_unittest.mm',
diff --git a/components/constrained_window/constrained_window_views.cc b/components/constrained_window/constrained_window_views.cc
index 5ae6cd77..3bf1dfc3 100644
--- a/components/constrained_window/constrained_window_views.cc
+++ b/components/constrained_window/constrained_window_views.cc
@@ -6,6 +6,7 @@
 
 #include <algorithm>
 
+#include "base/debug/alias.h"
 #include "components/constrained_window/constrained_window_views_client.h"
 #include "components/guest_view/browser/guest_view_base.h"
 #include "components/web_modal/web_contents_modal_dialog_host.h"
@@ -146,6 +147,12 @@
 
 views::Widget* CreateWebModalDialogViews(views::WidgetDelegate* dialog,
                                          content::WebContents* web_contents) {
+  // Temporary to track down http://crbug.com/538612
+  content::WebContentsDelegate* delegate = web_contents->GetDelegate();
+  base::debug::Alias(delegate);
+  CHECK(
+      web_modal::WebContentsModalDialogManager::FromWebContents(web_contents));
+
   DCHECK_EQ(ui::MODAL_TYPE_CHILD, dialog->GetModalType());
   return views::DialogDelegate::CreateDialogWidget(
       dialog, nullptr,
diff --git a/components/history.gypi b/components/history.gypi
index 16f1029..1252f59 100644
--- a/components/history.gypi
+++ b/components/history.gypi
@@ -243,6 +243,7 @@
     ['OS=="ios"', {
       'targets': [
         {
+          # GN version: //components/history/ios/browser
           'target_name': 'history_ios_browser',
           'type': 'static_library',
           'include_dirs': [
diff --git a/components/history/ios/browser/BUILD.gn b/components/history/ios/browser/BUILD.gn
new file mode 100644
index 0000000..960d778
--- /dev/null
+++ b/components/history/ios/browser/BUILD.gn
@@ -0,0 +1,19 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+source_set("browser") {
+  sources = [
+    "history_database_helper.cc",
+    "history_database_helper.h",
+    "web_state_top_sites_observer.cc",
+    "web_state_top_sites_observer.h",
+  ]
+
+  deps = [
+    "//base",
+    "//components/history/core/browser",
+    "//ios/web",
+    "//url",
+  ]
+}
diff --git a/components/nacl/renderer/progress_event.cc b/components/nacl/renderer/progress_event.cc
index ae30755..6bd5571 100644
--- a/components/nacl/renderer/progress_event.cc
+++ b/components/nacl/renderer/progress_event.cc
@@ -6,88 +6,63 @@
 
 #include "base/bind.h"
 #include "base/location.h"
-#include "base/logging.h"
 #include "components/nacl/renderer/ppb_nacl_private.h"
 #include "content/public/renderer/pepper_plugin_instance.h"
 #include "ppapi/shared_impl/ppapi_globals.h"
 #include "third_party/WebKit/public/platform/WebString.h"
-#include "third_party/WebKit/public/web/WebDOMResourceProgressEvent.h"
-#include "third_party/WebKit/public/web/WebDocument.h"
-#include "third_party/WebKit/public/web/WebElement.h"
-#include "third_party/WebKit/public/web/WebLocalFrame.h"
 #include "third_party/WebKit/public/web/WebPluginContainer.h"
-#include "v8/include/v8.h"
+
+using blink::WebString;
+using blink::WebPluginContainer;
 
 namespace nacl {
 
 namespace {
-blink::WebString EventTypeToString(PP_NaClEventType event_type) {
+const char* EventTypeToName(PP_NaClEventType event_type) {
   switch (event_type) {
     case PP_NACL_EVENT_LOADSTART:
-      return blink::WebString::fromUTF8("loadstart");
+      return "loadstart";
     case PP_NACL_EVENT_PROGRESS:
-      return blink::WebString::fromUTF8("progress");
+      return "progress";
     case PP_NACL_EVENT_ERROR:
-      return blink::WebString::fromUTF8("error");
+      return "error";
     case PP_NACL_EVENT_ABORT:
-      return blink::WebString::fromUTF8("abort");
+      return "abort";
     case PP_NACL_EVENT_LOAD:
-      return blink::WebString::fromUTF8("load");
+      return "load";
     case PP_NACL_EVENT_LOADEND:
-      return blink::WebString::fromUTF8("loadend");
+      return "loadend";
     case PP_NACL_EVENT_CRASH:
-      return blink::WebString::fromUTF8("crash");
+      return "crash";
   }
-  NOTIMPLEMENTED();
-  return blink::WebString();
+  NOTREACHED();
+  return "";
 }
 
 void DispatchProgressEventOnMainThread(PP_Instance instance,
-                                       const ProgressEvent &event) {
+                                       const ProgressEvent& event) {
   content::PepperPluginInstance* plugin_instance =
       content::PepperPluginInstance::Get(instance);
   if (!plugin_instance)
     return;
 
-  blink::WebPluginContainer* container = plugin_instance->GetContainer();
+  WebPluginContainer* container = plugin_instance->GetContainer();
   // It's possible that container() is NULL if the plugin has been removed from
   // the DOM (but the PluginInstance is not destroyed yet).
   if (!container)
     return;
-  blink::WebLocalFrame* frame = container->element().document().frame();
-  if (!frame)
-    return;
-  v8::HandleScope handle_scope(plugin_instance->GetIsolate());
-  v8::Local<v8::Context> context(
-      plugin_instance->GetIsolate()->GetCurrentContext());
-  if (context.IsEmpty()) {
-    // If there's no JavaScript on the stack, we have to make a new Context.
-    context = v8::Context::New(plugin_instance->GetIsolate());
-  }
-  v8::Context::Scope context_scope(context);
 
-  if (!event.resource_url.empty()) {
-    blink::WebString url_string = blink::WebString::fromUTF8(
-        event.resource_url.data(), event.resource_url.size());
-    blink::WebDOMResourceProgressEvent blink_event(
-        EventTypeToString(event.event_type),
-        event.length_is_computable,
-        event.loaded_bytes,
-        event.total_bytes,
-        url_string);
-    container->element().dispatchEvent(blink_event);
-  } else {
-    blink::WebDOMProgressEvent blink_event(EventTypeToString(event.event_type),
-                                           event.length_is_computable,
-                                           event.loaded_bytes,
-                                           event.total_bytes);
-    container->element().dispatchEvent(blink_event);
-  }
+  container->dispatchProgressEvent(
+      WebString::fromUTF8(EventTypeToName(event.event_type)),
+      event.length_is_computable,
+      event.loaded_bytes,
+      event.total_bytes,
+      WebString::fromUTF8(event.resource_url));
 }
 
 }  // namespace
 
-void DispatchProgressEvent(PP_Instance instance, const ProgressEvent &event) {
+void DispatchProgressEvent(PP_Instance instance, const ProgressEvent& event) {
   ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask(
       FROM_HERE,
       base::Bind(&DispatchProgressEventOnMainThread, instance, event));
diff --git a/components/page_load_metrics/browser/metrics_web_contents_observer.cc b/components/page_load_metrics/browser/metrics_web_contents_observer.cc
index 6e2feb75..ffda133 100644
--- a/components/page_load_metrics/browser/metrics_web_contents_observer.cc
+++ b/components/page_load_metrics/browser/metrics_web_contents_observer.cc
@@ -77,11 +77,6 @@
   return true;
 }
 
-base::Time WallTimeFromTimeTicks(const base::TimeTicks& time) {
-  return base::Time::FromDoubleT(
-      (time - base::TimeTicks::UnixEpoch()).InSecondsF());
-}
-
 void RecordInternalError(InternalErrorLoadEvent event) {
   UMA_HISTOGRAM_ENUMERATION(kErrorEvents, event, ERR_LAST_ENTRY);
 }
@@ -122,8 +117,10 @@
 PageLoadTracker::PageLoadTracker(
     bool in_foreground,
     PageLoadMetricsEmbedderInterface* embedder_interface,
+    content::NavigationHandle* navigation_handle,
     base::ObserverList<PageLoadMetricsObserver, true>* observers)
     : has_commit_(false),
+      navigation_start_(navigation_handle->NavigationStart()),
       started_in_foreground_(in_foreground),
       embedder_interface_(embedder_interface),
       observers_(observers) {}
@@ -187,14 +184,10 @@
 PageLoadExtraInfo PageLoadTracker::GetPageLoadMetricsInfo() {
   base::TimeDelta first_background_time;
   base::TimeDelta first_foreground_time;
-  if (!background_time_.is_null() && started_in_foreground_) {
-    first_background_time =
-        WallTimeFromTimeTicks(background_time_) - timing_.navigation_start;
-  }
-  if (!foreground_time_.is_null() && !started_in_foreground_) {
-    first_foreground_time =
-        WallTimeFromTimeTicks(foreground_time_) - timing_.navigation_start;
-  }
+  if (!background_time_.is_null() && started_in_foreground_)
+    first_background_time = background_time_ - navigation_start_;
+  if (!foreground_time_.is_null() && !started_in_foreground_)
+    first_foreground_time = foreground_time_ - navigation_start_;
   return PageLoadExtraInfo(first_background_time, first_foreground_time,
                            started_in_foreground_);
 }
@@ -218,9 +211,8 @@
 //    backgrounded.
 base::TimeDelta PageLoadTracker::GetBackgroundDelta() {
   if (started_in_foreground_) {
-    if (background_time_.is_null())
-      return base::TimeDelta::Max();
-    return WallTimeFromTimeTicks(background_time_) - timing_.navigation_start;
+    return background_time_.is_null() ? base::TimeDelta::Max()
+                                      : background_time_ - navigation_start_;
   }
   return base::TimeDelta();
 }
@@ -306,9 +298,8 @@
   if (!background_time_.is_null()) {
     PAGE_LOAD_HISTOGRAM(kHistogramFirstBackground, background_delta);
   } else if (!foreground_time_.is_null()) {
-    PAGE_LOAD_HISTOGRAM(
-        kHistogramFirstForeground,
-        WallTimeFromTimeTicks(foreground_time_) - timing_.navigation_start);
+    PAGE_LOAD_HISTOGRAM(kHistogramFirstForeground,
+                        foreground_time_ - navigation_start_);
   }
 }
 
@@ -427,10 +418,10 @@
   // Passing raw pointers to observers_ and embedder_interface_ is safe because
   // the MetricsWebContentsObserver owns them both list and they are torn down
   // after the PageLoadTracker.
-  provisional_loads_.insert(
-      navigation_handle,
-      make_scoped_ptr(new PageLoadTracker(
-          in_foreground_, embedder_interface_.get(), &observers_)));
+  provisional_loads_.insert(navigation_handle,
+                            make_scoped_ptr(new PageLoadTracker(
+                                in_foreground_, embedder_interface_.get(),
+                                navigation_handle, &observers_)));
 }
 
 void MetricsWebContentsObserver::DidFinishNavigation(
diff --git a/components/page_load_metrics/browser/metrics_web_contents_observer.h b/components/page_load_metrics/browser/metrics_web_contents_observer.h
index c9685b6..1c8a4e5 100644
--- a/components/page_load_metrics/browser/metrics_web_contents_observer.h
+++ b/components/page_load_metrics/browser/metrics_web_contents_observer.h
@@ -195,6 +195,7 @@
   // outlives this class.
   PageLoadTracker(bool in_foreground,
                   PageLoadMetricsEmbedderInterface* embedder_interface,
+                  content::NavigationHandle* navigation_handle,
                   base::ObserverList<PageLoadMetricsObserver, true>* observers);
   ~PageLoadTracker();
   void Redirect(content::NavigationHandle* navigation_handle);
@@ -219,6 +220,9 @@
 
   bool has_commit_;
 
+  // The navigation start in TimeTicks, not the wall time reported by Blink.
+  const base::TimeTicks navigation_start_;
+
   // We record separate metrics for events that occur after a background,
   // because metrics like layout/paint are delayed artificially
   // when they occur in the background.
diff --git a/components/page_load_metrics/browser/metrics_web_contents_observer_unittest.cc b/components/page_load_metrics/browser/metrics_web_contents_observer_unittest.cc
index 769c237..b1f3228f 100644
--- a/components/page_load_metrics/browser/metrics_web_contents_observer_unittest.cc
+++ b/components/page_load_metrics/browser/metrics_web_contents_observer_unittest.cc
@@ -302,8 +302,7 @@
   base::TimeDelta first_layout = base::TimeDelta::FromSeconds(2);
 
   PageLoadTiming timing;
-  timing.navigation_start = base::Time::FromDoubleT(
-      (base::TimeTicks::Now() - base::TimeTicks::UnixEpoch()).InSecondsF());
+  timing.navigation_start = base::Time::FromDoubleT(1);
   timing.first_layout = first_layout;
 
   content::WebContentsTester* web_contents_tester =
@@ -356,11 +355,11 @@
 
 TEST_F(MetricsWebContentsObserverTest, OnlyBackgroundLaterEvents) {
   PageLoadTiming timing;
-  timing.navigation_start = base::Time::FromDoubleT(
-      (base::TimeTicks::Now() - base::TimeTicks::UnixEpoch()).InSecondsF() - 1);
-
-  timing.response_start = base::TimeDelta::FromMilliseconds(1);
-  timing.dom_content_loaded_event_start = base::TimeDelta::FromMilliseconds(1);
+  timing.navigation_start = base::Time::FromDoubleT(1);
+  // Set these events at 1 microsecond so they are definitely occur before we
+  // background the tab later in the test.
+  timing.response_start = base::TimeDelta::FromMicroseconds(1);
+  timing.dom_content_loaded_event_start = base::TimeDelta::FromMicroseconds(1);
 
   content::WebContentsTester* web_contents_tester =
       content::WebContentsTester::For(web_contents());
@@ -402,7 +401,9 @@
 }
 
 TEST_F(MetricsWebContentsObserverTest, DontBackgroundQuickerLoad) {
-  base::TimeDelta first_layout = base::TimeDelta::FromMilliseconds(1);
+  // Set this event at 1 microsecond so it occurs before we foreground later in
+  // the test.
+  base::TimeDelta first_layout = base::TimeDelta::FromMicroseconds(1);
 
   PageLoadTiming timing;
   timing.navigation_start = base::Time::FromDoubleT(1);
@@ -430,7 +431,7 @@
       main_rfh());
   rfh_tester->SimulateNavigationStop();
 
-  // Navigate again to see if the timing updated for a subframe message.
+  // Navigate again to see if the timing updated for the foregrounded load.
   web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl));
 
   histogram_tester_.ExpectTotalCount(kHistogramDomContentLoaded, 0);
@@ -578,9 +579,7 @@
 TEST_F(MetricsWebContentsObserverTest,
        SuccessfulFirstLayoutInBackgroundEvent) {
   PageLoadTiming timing;
-  timing.navigation_start = base::Time::FromDoubleT(
-      (base::TimeTicks::Now() - base::TimeTicks::UnixEpoch()).InSecondsF() - 1);
-
+  timing.navigation_start = base::Time::FromDoubleT(1);
   timing.first_layout = base::TimeDelta::FromSeconds(30);
 
   content::WebContentsTester* web_contents_tester =
diff --git a/components/password_manager.gypi b/components/password_manager.gypi
index 6e941e5..15bcbf9 100644
--- a/components/password_manager.gypi
+++ b/components/password_manager.gypi
@@ -106,8 +106,6 @@
         'password_manager/core/browser/password_store_default.h',
         'password_manager/core/browser/password_store_factory_util.cc',
         'password_manager/core/browser/password_store_factory_util.h',
-        'password_manager/core/browser/password_store_service.cc',
-        'password_manager/core/browser/password_store_service.h',
         'password_manager/core/browser/password_store_sync.cc',
         'password_manager/core/browser/password_store_sync.h',
         'password_manager/core/browser/password_syncable_service.cc',
diff --git a/components/password_manager/content/browser/credential_manager_dispatcher_unittest.cc b/components/password_manager/content/browser/credential_manager_dispatcher_unittest.cc
index 7052a6f..00111fb1 100644
--- a/components/password_manager/content/browser/credential_manager_dispatcher_unittest.cc
+++ b/components/password_manager/content/browser/credential_manager_dispatcher_unittest.cc
@@ -224,7 +224,7 @@
   }
 
   void TearDown() override {
-    store_->Shutdown();
+    store_->ShutdownOnUIThread();
     content::RenderViewHostTestHarness::TearDown();
   }
 
diff --git a/components/password_manager/core/browser/BUILD.gn b/components/password_manager/core/browser/BUILD.gn
index a560e12c..35207d2 100644
--- a/components/password_manager/core/browser/BUILD.gn
+++ b/components/password_manager/core/browser/BUILD.gn
@@ -86,8 +86,6 @@
     "password_store_default.h",
     "password_store_factory_util.cc",
     "password_store_factory_util.h",
-    "password_store_service.cc",
-    "password_store_service.h",
     "password_store_sync.cc",
     "password_store_sync.h",
     "password_syncable_service.cc",
diff --git a/components/password_manager/core/browser/affiliated_match_helper_unittest.cc b/components/password_manager/core/browser/affiliated_match_helper_unittest.cc
index 633924f..946678df 100644
--- a/components/password_manager/core/browser/affiliated_match_helper_unittest.cc
+++ b/components/password_manager/core/browser/affiliated_match_helper_unittest.cc
@@ -296,7 +296,7 @@
 
   void TearDown() override {
     match_helper_.reset();
-    password_store_->Shutdown();
+    password_store_->ShutdownOnUIThread();
     password_store_ = nullptr;
   }
 
diff --git a/components/password_manager/core/browser/password_form_manager_unittest.cc b/components/password_manager/core/browser/password_form_manager_unittest.cc
index f2eb36b9..4c24a13 100644
--- a/components/password_manager/core/browser/password_form_manager_unittest.cc
+++ b/components/password_manager/core/browser/password_form_manager_unittest.cc
@@ -313,7 +313,7 @@
 
   void TearDown() override {
     if (mock_store_.get())
-      mock_store_->Shutdown();
+      mock_store_->ShutdownOnUIThread();
   }
 
   MockPasswordStore* mock_store() const { return mock_store_.get(); }
diff --git a/components/password_manager/core/browser/password_generation_manager_unittest.cc b/components/password_manager/core/browser/password_generation_manager_unittest.cc
index c687748d..fcc2683 100644
--- a/components/password_manager/core/browser/password_generation_manager_unittest.cc
+++ b/components/password_manager/core/browser/password_generation_manager_unittest.cc
@@ -74,7 +74,7 @@
   explicit MockPasswordManagerClient(scoped_ptr<PrefService> prefs)
       : prefs_(prefs.Pass()), store_(new TestPasswordStore), driver_(this) {}
 
-  ~MockPasswordManagerClient() override { store_->Shutdown(); }
+  ~MockPasswordManagerClient() override { store_->ShutdownOnUIThread(); }
 
   PasswordStore* GetPasswordStore() const override { return store_.get(); }
   PrefService* GetPrefs() override { return prefs_.get(); }
diff --git a/components/password_manager/core/browser/password_manager_test_utils.h b/components/password_manager/core/browser/password_manager_test_utils.h
index aeb212f..c6e7c6a3 100644
--- a/components/password_manager/core/browser/password_manager_test_utils.h
+++ b/components/password_manager/core/browser/password_manager_test_utils.h
@@ -8,9 +8,9 @@
 #include <iosfwd>
 #include <vector>
 
-#include "base/memory/scoped_ptr.h"
+#include "base/memory/ref_counted.h"
 #include "components/autofill/core/common/password_form.h"
-#include "components/password_manager/core/browser/password_store_service.h"
+#include "components/password_manager/core/browser/password_store.h"
 #include "testing/gmock/include/gmock/gmock.h"
 
 // TODO(sync): The PasswordFormData code must eventually be refactored away --
@@ -18,17 +18,17 @@
 
 namespace password_manager {
 
-// This templates allows creating methods with signature conforming to
+// This template allows creating methods with signature conforming to
 // TestingFactoryFunction of the appropriate platform instance of
 // KeyedServiceFactory. Context is the browser context prescribed by
 // TestingFactoryFunction. Store is the PasswordStore version needed in the
 // tests which use this method.
 template <class Context, class Store>
-scoped_ptr<KeyedService> BuildPasswordStoreService(Context* context) {
+scoped_refptr<RefcountedKeyedService> BuildPasswordStore(Context* context) {
   scoped_refptr<password_manager::PasswordStore> store(new Store);
   if (!store->Init(syncer::SyncableService::StartSyncFlare()))
     return nullptr;
-  return scoped_ptr<KeyedService>(new PasswordStoreService(store));
+  return store;
 }
 
 // These constants are used by CreatePasswordFormFromDataForTesting to supply
diff --git a/components/password_manager/core/browser/password_manager_unittest.cc b/components/password_manager/core/browser/password_manager_unittest.cc
index 6fb28b50..2978f56 100644
--- a/components/password_manager/core/browser/password_manager_unittest.cc
+++ b/components/password_manager/core/browser/password_manager_unittest.cc
@@ -135,7 +135,7 @@
   }
 
   void TearDown() override {
-    store_->Shutdown();
+    store_->ShutdownOnUIThread();
     store_ = nullptr;
   }
 
diff --git a/components/password_manager/core/browser/password_store.cc b/components/password_manager/core/browser/password_store.cc
index 560a2928..b960bf5 100644
--- a/components/password_manager/core/browser/password_store.cc
+++ b/components/password_manager/core/browser/password_store.cc
@@ -235,7 +235,7 @@
   return false;
 }
 
-void PasswordStore::Shutdown() {
+void PasswordStore::ShutdownOnUIThread() {
   ScheduleTask(base::Bind(&PasswordStore::DestroySyncableService, this));
   // The AffiliationService must be destroyed from the main thread.
   affiliated_match_helper_.reset();
diff --git a/components/password_manager/core/browser/password_store.h b/components/password_manager/core/browser/password_store.h
index ceeaece5..aedccbc 100644
--- a/components/password_manager/core/browser/password_store.h
+++ b/components/password_manager/core/browser/password_store.h
@@ -10,12 +10,12 @@
 
 #include "base/callback.h"
 #include "base/gtest_prod_util.h"
-#include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/scoped_vector.h"
 #include "base/observer_list_threadsafe.h"
 #include "base/single_thread_task_runner.h"
 #include "base/time/time.h"
+#include "components/keyed_service/core/refcounted_keyed_service.h"
 #include "components/password_manager/core/browser/password_store_change.h"
 #include "components/password_manager/core/browser/password_store_sync.h"
 #include "sync/api/syncable_service.h"
@@ -52,7 +52,7 @@
 // PasswordStoreSync is a hidden base class because only PasswordSyncableService
 // needs to access these methods.
 class PasswordStore : protected PasswordStoreSync,
-                      public base::RefCountedThreadSafe<PasswordStore> {
+                      public RefcountedKeyedService {
  public:
   // Whether or not it's acceptable for Chrome to request access to locked
   // passwords, which requires prompting the user for permission.
@@ -77,6 +77,9 @@
   // Reimplement this to add custom initialization. Always call this too.
   virtual bool Init(const syncer::SyncableService::StartSyncFlare& flare);
 
+  // RefcountedKeyedService:
+  void ShutdownOnUIThread() override;
+
   // Sets the affiliation-based match |helper| that will be used by subsequent
   // GetLogins() calls to return credentials stored not only for the requested
   // sign-on realm, but also for affiliated Android applications. If |helper| is
@@ -191,10 +194,6 @@
   // Schedules the given |task| to be run on the PasswordStore's TaskRunner.
   bool ScheduleTask(const base::Closure& task);
 
-  // Before you destruct the store, call Shutdown to indicate that the store
-  // needs to shut itself down.
-  virtual void Shutdown();
-
   base::WeakPtr<syncer::SyncableService> GetPasswordSyncableService();
 
  protected:
diff --git a/components/password_manager/core/browser/password_store_default.cc b/components/password_manager/core/browser/password_store_default.cc
index ad65039..dab5c29 100644
--- a/components/password_manager/core/browser/password_store_default.cc
+++ b/components/password_manager/core/browser/password_store_default.cc
@@ -33,8 +33,8 @@
   return PasswordStore::Init(flare);
 }
 
-void PasswordStoreDefault::Shutdown() {
-  PasswordStore::Shutdown();
+void PasswordStoreDefault::ShutdownOnUIThread() {
+  PasswordStore::ShutdownOnUIThread();
   ScheduleTask(base::Bind(&PasswordStoreDefault::ResetLoginDB, this));
 }
 
diff --git a/components/password_manager/core/browser/password_store_default.h b/components/password_manager/core/browser/password_store_default.h
index af5bdc6..3d714bd 100644
--- a/components/password_manager/core/browser/password_store_default.h
+++ b/components/password_manager/core/browser/password_store_default.h
@@ -27,7 +27,7 @@
 
   bool Init(const syncer::SyncableService::StartSyncFlare& flare) override;
 
-  void Shutdown() override;
+  void ShutdownOnUIThread() override;
 
   // To be used only for testing.
   LoginDatabase* login_db() const { return login_db_.get(); }
diff --git a/components/password_manager/core/browser/password_store_default_unittest.cc b/components/password_manager/core/browser/password_store_default_unittest.cc
index 53080d9..b9e9c581 100644
--- a/components/password_manager/core/browser/password_store_default_unittest.cc
+++ b/components/password_manager/core/browser/password_store_default_unittest.cc
@@ -172,7 +172,7 @@
 
   base::MessageLoop::current()->RunUntilIdle();
 
-  store->Shutdown();
+  store->ShutdownOnUIThread();
 }
 
 TEST_F(PasswordStoreDefaultTest, Notifications) {
@@ -221,7 +221,7 @@
   base::MessageLoop::current()->RunUntilIdle();
 
   store->RemoveObserver(&observer);
-  store->Shutdown();
+  store->ShutdownOnUIThread();
 }
 
 // Verify that operations on a PasswordStore with a bad database cause no
@@ -285,7 +285,7 @@
 
   // Ensure no notifications and no explosions during shutdown either.
   bad_store->RemoveObserver(&mock_observer);
-  bad_store->Shutdown();
+  bad_store->ShutdownOnUIThread();
 }
 
 TEST_F(PasswordStoreDefaultTest,
@@ -311,7 +311,7 @@
   run_loop.Run();
 
   store->RemoveObserver(&observer);
-  store->Shutdown();
+  store->ShutdownOnUIThread();
 }
 
 TEST_F(PasswordStoreDefaultTest,
@@ -336,7 +336,7 @@
   run_loop.Run();
 
   store->RemoveObserver(&observer);
-  store->Shutdown();
+  store->ShutdownOnUIThread();
 }
 
 TEST_F(PasswordStoreDefaultTest,
@@ -363,7 +363,7 @@
   run_loop.Run();
 
   store->RemoveObserver(&observer);
-  store->Shutdown();
+  store->ShutdownOnUIThread();
 }
 
 }  // namespace password_manager
diff --git a/components/password_manager/core/browser/password_store_factory_util.cc b/components/password_manager/core/browser/password_store_factory_util.cc
index e6c8580..eaf114b 100644
--- a/components/password_manager/core/browser/password_store_factory_util.cc
+++ b/components/password_manager/core/browser/password_store_factory_util.cc
@@ -88,34 +88,10 @@
   }
 }
 
-scoped_refptr<PasswordStore> GetPasswordStoreFromService(
-    password_manager::PasswordStoreService* service,
-    ServiceAccessType access_type,
-    bool is_off_the_record) {
-  if (access_type == ServiceAccessType::IMPLICIT_ACCESS && is_off_the_record) {
-    NOTREACHED() << "Incognito state does not have a password store associated";
-    return nullptr;
-  }
-
-  return service ? service->GetPasswordStore() : nullptr;
-}
-
 scoped_ptr<LoginDatabase> CreateLoginDatabase(
     const base::FilePath& profile_path) {
   base::FilePath login_db_file_path = profile_path.Append(kLoginDataFileName);
   return make_scoped_ptr(new LoginDatabase(login_db_file_path));
 }
 
-scoped_ptr<KeyedService> BuildServiceInstanceFromStore(
-    scoped_refptr<PasswordStore> store,
-    syncer::SyncableService::StartSyncFlare sync_flare) {
-  DCHECK(store);
-  if (!store->Init(sync_flare)) {
-    NOTREACHED() << "Could not initialize password store.";
-    return nullptr;
-  }
-
-  return make_scoped_ptr(new PasswordStoreService(store));
-}
-
 }  // namespace password_manager
diff --git a/components/password_manager/core/browser/password_store_factory_util.h b/components/password_manager/core/browser/password_store_factory_util.h
index 83a73b6..2626618 100644
--- a/components/password_manager/core/browser/password_store_factory_util.h
+++ b/components/password_manager/core/browser/password_store_factory_util.h
@@ -13,7 +13,6 @@
 #include "components/keyed_service/core/service_access_type.h"
 #include "components/password_manager/core/browser/login_database.h"
 #include "components/password_manager/core/browser/password_store.h"
-#include "components/password_manager/core/browser/password_store_service.h"
 #include "components/sync_driver/sync_service.h"
 #include "net/url_request/url_request_context_getter.h"
 #include "sync/api/syncable_service.h"
@@ -42,27 +41,12 @@
     const base::FilePath& profile_path,
     scoped_refptr<base::SingleThreadTaskRunner> db_thread_runner);
 
-// Extracts the PasswordStore from |service|, taking into account the
-// |access_type|, and whether the corresponding browsing session
-// |is_off_the_record|.
-scoped_refptr<PasswordStore> GetPasswordStoreFromService(
-    PasswordStoreService* service,
-    ServiceAccessType access_type,
-    bool is_off_the_record);
-
 // Creates a LoginDatabase. Looks in |profile_path| for the database file.
 // Does not call LoginDatabase::Init() -- to avoid UI jank, that needs to be
 // called by PasswordStore::Init() on the background thread.
 scoped_ptr<LoginDatabase> CreateLoginDatabase(
     const base::FilePath& profile_path);
 
-// Initializes the |store|, passing |sync_flare| into it, then returns the
-// |store| wrapped in a PasswordStoreService on success. Returns nullptr on
-// failure.
-scoped_ptr<KeyedService> BuildServiceInstanceFromStore(
-    scoped_refptr<PasswordStore> store,
-    syncer::SyncableService::StartSyncFlare sync_flare);
-
 }  // namespace password_manager
 
 #endif  // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_STORE_FACTORY_UTIL_H_
diff --git a/components/password_manager/core/browser/password_store_service.cc b/components/password_manager/core/browser/password_store_service.cc
deleted file mode 100644
index d66629d8..0000000
--- a/components/password_manager/core/browser/password_store_service.cc
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/password_manager/core/browser/password_store_service.h"
-
-namespace password_manager {
-
-PasswordStoreService::PasswordStoreService(
-    scoped_refptr<PasswordStore> password_store)
-    : password_store_(password_store) {}
-
-PasswordStoreService::~PasswordStoreService() {}
-
-scoped_refptr<PasswordStore> PasswordStoreService::GetPasswordStore() {
-  return password_store_;
-}
-
-void PasswordStoreService::Shutdown() {
-  if (password_store_)
-    password_store_->Shutdown();
-}
-
-}  // namespace password_manager
diff --git a/components/password_manager/core/browser/password_store_service.h b/components/password_manager/core/browser/password_store_service.h
deleted file mode 100644
index 0e57011..0000000
--- a/components/password_manager/core/browser/password_store_service.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_STORE_SERVICE_H_
-#define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_STORE_SERVICE_H_
-
-#include "base/memory/ref_counted.h"
-#include "components/keyed_service/core/keyed_service.h"
-#include "components/password_manager/core/browser/password_store.h"
-
-namespace password_manager {
-
-// A wrapper of PasswordStore so we can use it as a profiled keyed service. This
-// is necessary, because while the service has a signle owner (its factory), the
-// store is refcounted.
-class PasswordStoreService : public KeyedService {
- public:
-  // |password_store| needs to be not-NULL, and the constructor expects that
-  // Init() was already called successfully on it.
-  explicit PasswordStoreService(scoped_refptr<PasswordStore> password_store);
-  ~PasswordStoreService() override;
-
-  scoped_refptr<PasswordStore> GetPasswordStore();
-
-  // KeyedService implementation.
-  void Shutdown() override;
-
- private:
-  scoped_refptr<PasswordStore> password_store_;
-
-  DISALLOW_COPY_AND_ASSIGN(PasswordStoreService);
-};
-
-}  // namespace password_manager
-
-#endif  // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_STORE_SERVICE_H_
diff --git a/components/password_manager/core/browser/password_store_unittest.cc b/components/password_manager/core/browser/password_store_unittest.cc
index 619c38fe..bff9d6d 100644
--- a/components/password_manager/core/browser/password_store_unittest.cc
+++ b/components/password_manager/core/browser/password_store_unittest.cc
@@ -225,7 +225,7 @@
 
   base::MessageLoop::current()->RunUntilIdle();
 
-  store->Shutdown();
+  store->ShutdownOnUIThread();
   base::MessageLoop::current()->RunUntilIdle();
 }
 
@@ -244,7 +244,7 @@
     store->AddLogin(form);
     base::MessageLoop::current()->RunUntilIdle();
   }
-  store->Shutdown();
+  store->ShutdownOnUIThread();
   base::MessageLoop::current()->RunUntilIdle();
 }
 
@@ -294,7 +294,7 @@
   ASSERT_TRUE(returned_form);
   EXPECT_EQ(*test_form, *returned_form);
 
-  store->Shutdown();
+  store->ShutdownOnUIThread();
   base::MessageLoop::current()->RunUntilIdle();
 }
 
@@ -352,7 +352,7 @@
   base::MessageLoop::current()->RunUntilIdle();
 
   store->RemoveObserver(&mock_observer);
-  store->Shutdown();
+  store->ShutdownOnUIThread();
   base::MessageLoop::current()->RunUntilIdle();
 }
 
@@ -391,7 +391,7 @@
   testing::Mock::VerifyAndClearExpectations(&mock_observer);
 
   store->RemoveObserver(&mock_observer);
-  store->Shutdown();
+  store->ShutdownOnUIThread();
   base::MessageLoop::current()->RunUntilIdle();
 }
 
@@ -462,7 +462,7 @@
               OnGetPasswordStoreResultsConstRef(
                   UnorderedPasswordFormElementsAre(expected_results.get())));
   store->GetLogins(observed_form, PasswordStore::ALLOW_PROMPT, &mock_consumer);
-  store->Shutdown();
+  store->ShutdownOnUIThread();
   base::MessageLoop::current()->RunUntilIdle();
 }
 
@@ -580,7 +580,7 @@
                   UnorderedPasswordFormElementsAre(expected_results.get())));
 
   store->GetLogins(observed_form, PasswordStore::ALLOW_PROMPT, &mock_consumer);
-  store->Shutdown();
+  store->ShutdownOnUIThread();
   base::MessageLoop::current()->RunUntilIdle();
 }
 
@@ -797,7 +797,7 @@
           OnGetPasswordStoreResultsConstRef(UnorderedPasswordFormElementsAre(
               expected_credentials_after_update.get())));
       store->GetAutofillableLogins(&mock_consumer);
-      store->Shutdown();
+      store->ShutdownOnUIThread();
       base::MessageLoop::current()->RunUntilIdle();
     }
   }
diff --git a/components/password_manager/core/browser/password_syncable_service_unittest.cc b/components/password_manager/core/browser/password_syncable_service_unittest.cc
index abd13a8..7cbf476 100644
--- a/components/password_manager/core/browser/password_syncable_service_unittest.cc
+++ b/components/password_manager/core/browser/password_syncable_service_unittest.cc
@@ -195,7 +195,7 @@
     EXPECT_CALL(*password_store(), NotifyLoginsChanged(_)).Times(AnyNumber());
   }
 
-  ~PasswordSyncableServiceWrapper() { password_store_->Shutdown(); }
+  ~PasswordSyncableServiceWrapper() { password_store_->ShutdownOnUIThread(); }
 
   MockPasswordStore* password_store() { return password_store_.get(); }
 
diff --git a/components/policy/core/common/cloud/cloud_policy_constants.h b/components/policy/core/common/cloud/cloud_policy_constants.h
index a173275..e1a9134 100644
--- a/components/policy/core/common/cloud/cloud_policy_constants.h
+++ b/components/policy/core/common/cloud/cloud_policy_constants.h
@@ -65,16 +65,6 @@
 POLICY_EXPORT std::string GetPolicyVerificationKey();
 POLICY_EXPORT extern const char kPolicyVerificationKeyHash[];
 
-// TODO(peletskyi): Remove this enum after affiliation code is moved
-// to components/user_manager.
-// Describes the affiliation of a user w.r.t. the device owner.
-enum UserAffiliation {
-  // User is on the same domain the device was registered with.
-  USER_AFFILIATION_MANAGED,
-  // No affiliation between device and user.
-  USER_AFFILIATION_NONE,
-};
-
 // Status codes for communication errors with the device management service.
 // This enum is used to define the buckets for an enumerated UMA histogram.
 // Hence,
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json
index ef935c11..046a437 100644
--- a/components/policy/resources/policy_templates.json
+++ b/components/policy/resources/policy_templates.json
@@ -134,7 +134,7 @@
 #   persistent IDs for all fields (but not for groups!) are needed. These are
 #   specified by the 'id' keys of each policy. NEVER CHANGE EXISTING IDs,
 #   because doing so would break the deployed wire format!
-#   For your editing convenience: highest ID currently used: 310
+#   For your editing convenience: highest ID currently used: 311
 #
 # Placeholders:
 #   The following placeholder strings are automatically substituted:
@@ -8002,6 +8002,58 @@
       If this policy is set to false or unset, Unified Desktop will be
       disabled. In this case, the user cannot enable the feature.''',
     },
+    {
+      'name': 'DisplayRotationDefault',
+      'type': 'int-enum',
+      'schema': {
+        'type': 'integer',
+        'enum': [ 0, 1, 2, 3 ],
+      },
+      'items': [
+        {
+          'name': 'ROTATE_0',
+          'value': 0,
+          'caption': '''Rotate screen by 0 degrees''',
+        },
+        {
+          'name': 'ROTATE_90',
+          'value': 1,
+          'caption': '''Rotate screen clockwise by 90 degrees''',
+        },
+        {
+          'name': 'ROTATE_180',
+          'value': 2,
+          'caption': '''Rotate screen by 180 degrees''',
+        },
+        {
+          'name': 'ROTATE_270',
+          'value': 3,
+          'caption': '''Rotate screen clockwise by 270 degrees''',
+        },
+      ],
+      'supported_on': ['chrome_os:48-'],
+      'device_only': True,
+      'features': {
+        'can_be_recommended': False,
+        'dynamic_refresh': True,
+        'per_profile': False,
+      },
+      'example_value': 1,
+      'id': 311,
+      'caption': '''Set default display rotation, reapplied on every reboot''',
+      'tags': [],
+      'desc': '''If this policy is set, each display is rotated to the
+      specified orientation on every reboot, and the first time it is connected
+      after the policy value has changed. Users may change the display
+      rotation via the settings page after logging in, but their
+      setting will be overridden by the policy value at the next reboot.
+
+      This policy applies to both the primary and all secondary displays.
+
+      If the policy is not set, the default value is 0 degrees and the user is
+      free to change it. In this case, the default value is not reapplied at
+      restart.''',
+    },
   ],
   'messages': {
     # Messages that are not associated to any policies.
diff --git a/components/translate.gypi b/components/translate.gypi
index 2b0e48f..be9317b 100644
--- a/components/translate.gypi
+++ b/components/translate.gypi
@@ -233,6 +233,7 @@
     ['OS == "ios"', {
       'targets': [
         {
+          # GN version: //components/translate/ios/browser
           'target_name': 'translate_ios_browser',
           'type': 'static_library',
           'include_dirs': [
@@ -261,6 +262,7 @@
           ],
         },
         {
+          # GN version: //components/translate/ios/browser:injected_js
           'target_name': 'translate_ios_injected_js',
           'type': 'none',
           'sources': [
diff --git a/components/translate/ios/browser/BUILD.gn b/components/translate/ios/browser/BUILD.gn
new file mode 100644
index 0000000..420954a
--- /dev/null
+++ b/components/translate/ios/browser/BUILD.gn
@@ -0,0 +1,59 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//ios/web/js_compile.gni")
+
+source_set("browser") {
+  sources = [
+    "ios_translate_driver.h",
+    "ios_translate_driver.mm",
+    "js_language_detection_manager.h",
+    "js_language_detection_manager.mm",
+    "js_translate_manager.h",
+    "js_translate_manager.mm",
+    "language_detection_controller.h",
+    "language_detection_controller.mm",
+    "translate_controller.h",
+    "translate_controller.mm",
+  ]
+
+  deps = [
+    "//base",
+    "//components/translate/core/browser",
+    "//components/translate/core/common",
+    "//components/translate/core/language_detection",
+    "//ios/web",
+    "//url",
+    ":injected_js",
+  ]
+}
+
+js_compile_checked("injected_js") {
+  visibility = [ ":browser" ]
+  sources = [
+    "resources/language_detection.js",
+    "resources/translate_ios.js",
+  ]
+}
+
+source_set("unit_tests") {
+  testonly = true
+  sources = [
+    "js_translate_manager_unittest.mm",
+    "language_detection_controller_unittest.mm",
+    "translate_controller_unittest.mm",
+  ]
+
+  deps = [
+    "//base",
+    "//components/resources",
+    "//components/translate/core/common",
+    "//ios/web:test_support",
+    "//testing/gtest",
+    "//third_party/ocmock",
+    "//ui/base",
+    "//url",
+    ":browser",
+  ]
+}
diff --git a/content/browser/background_sync/background_sync_browsertest.cc b/content/browser/background_sync/background_sync_browsertest.cc
index e3f8dc0..6e30cc5 100644
--- a/content/browser/background_sync/background_sync_browsertest.cc
+++ b/content/browser/background_sync/background_sync_browsertest.cc
@@ -182,8 +182,6 @@
   bool RegisterServiceWorker();
   bool RegisterOneShot(const std::string& tag);
   bool RegisterOneShotFromServiceWorker(const std::string& tag);
-  bool UnregisterOneShot(const std::string& tag);
-  bool UnregisterOneShotTwice(const std::string& tag);
   bool GetRegistrationOneShot(const std::string& tag);
   bool GetRegistrationOneShotFromServiceWorker(const std::string& tag);
   bool MatchRegistrations(const std::string& script_result,
@@ -193,9 +191,6 @@
       const std::vector<std::string>& expected_tags);
   bool CompleteDelayedOneShot();
   bool RejectDelayedOneShot();
-  bool NotifyWhenFinishedOneShot(const std::string& tag);
-  bool NotifyWhenFinishedImmediateOneShot(const std::string& expected_msg);
-  bool StoreRegistrationOneShot(const std::string& tag);
 
  private:
   scoped_ptr<net::EmbeddedTestServer> https_server_;
@@ -323,21 +318,6 @@
   return script_result == BuildExpectedResult(tag, "register sent to SW");
 }
 
-bool BackgroundSyncBrowserTest::UnregisterOneShot(const std::string& tag) {
-  std::string script_result;
-  EXPECT_TRUE(
-      RunScript(BuildScriptString("unregisterOneShot", tag), &script_result));
-  return script_result == BuildExpectedResult(tag, "unregistered");
-}
-
-bool BackgroundSyncBrowserTest::UnregisterOneShotTwice(const std::string& tag) {
-  std::string script_result;
-  EXPECT_TRUE(RunScript(BuildScriptString("unregisterOneShotTwice", tag),
-                        &script_result));
-  return script_result ==
-         BuildExpectedResult(tag, "failed to unregister twice");
-}
-
 bool BackgroundSyncBrowserTest::GetRegistrationOneShot(const std::string& tag) {
   std::string script_result;
   EXPECT_TRUE(RunScript(BuildScriptString("getRegistrationOneShot", tag),
@@ -400,30 +380,6 @@
   return script_result == BuildExpectedResult("delay", "rejecting");
 }
 
-bool BackgroundSyncBrowserTest::NotifyWhenFinishedOneShot(
-    const std::string& tag) {
-  EXPECT_TRUE(content::ExecuteScript(
-      shell_->web_contents(),
-      BuildScriptString("notifyWhenFinishedOneShot", tag)));
-  return PopConsole(BuildExpectedResult(tag, "finished"));
-}
-
-bool BackgroundSyncBrowserTest::NotifyWhenFinishedImmediateOneShot(
-    const std::string& expected_msg) {
-  std::string script_result;
-  EXPECT_TRUE(
-      RunScript("notifyWhenFinishedImmediateOneShot()", &script_result));
-  return script_result == expected_msg;
-}
-
-bool BackgroundSyncBrowserTest::StoreRegistrationOneShot(
-    const std::string& tag) {
-  std::string script_result;
-  EXPECT_TRUE(
-      RunScript(BuildScriptString("storeRegistration", tag), &script_result));
-  return script_result == BuildExpectedResult(tag, "stored");
-}
-
 IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, OneShotFires) {
   EXPECT_TRUE(RegisterServiceWorker());
   EXPECT_TRUE(LoadTestPage(kDefaultTestURL));  // Control the page.
@@ -477,8 +433,6 @@
   EXPECT_TRUE(PopConsole("ok - delay completed"));
 
   // Verify that it finished firing.
-  // TODO(jkarlin): Use registration.finished to verify that the event actually
-  // completed successfully.
   EXPECT_FALSE(GetRegistrationOneShot("delay"));
 }
 
@@ -586,108 +540,6 @@
   EXPECT_TRUE(GetRegistrationOneShotFromServiceWorker("foo_sw"));
 }
 
-IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, Unregister) {
-  EXPECT_TRUE(RegisterServiceWorker());
-  EXPECT_TRUE(LoadTestPage(kDefaultTestURL));  // Control the page.
-
-  SetOnline(false);
-  EXPECT_TRUE(RegisterOneShot("foo"));
-  EXPECT_TRUE(UnregisterOneShot("foo"));
-  EXPECT_FALSE(GetRegistrationOneShot("foo"));
-}
-
-IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, UnregisterTwice) {
-  EXPECT_TRUE(RegisterServiceWorker());
-  EXPECT_TRUE(LoadTestPage(kDefaultTestURL));  // Control the page.
-
-  SetOnline(false);
-  EXPECT_TRUE(RegisterOneShot("foo"));
-  EXPECT_TRUE(UnregisterOneShotTwice("foo"));
-  EXPECT_FALSE(GetRegistrationOneShot("foo"));
-}
-
-IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, UnregisterMidSync) {
-  EXPECT_TRUE(RegisterServiceWorker());
-  EXPECT_TRUE(LoadTestPage(kDefaultTestURL));  // Control the page.
-
-  EXPECT_TRUE(RegisterOneShot("unregister"));
-  EXPECT_TRUE(PopConsole("ok - unregister completed"));
-}
-
-IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest,
-                       CallFinishedBeforeSyncSucceeds) {
-  EXPECT_TRUE(RegisterServiceWorker());
-  EXPECT_TRUE(LoadTestPage(kDefaultTestURL));  // Control the page.
-
-  SetOnline(false);
-  EXPECT_TRUE(RegisterOneShot("foo"));
-  EXPECT_TRUE(NotifyWhenFinishedOneShot("foo"));
-
-  SetOnline(true);
-  // The ordering of PopConsole messages tells us that the event fired
-  // before finished resolved.
-  EXPECT_TRUE(PopConsole("foo fired"));
-  EXPECT_TRUE(PopConsole("foo finished result: true"));
-}
-
-IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, CallFinishedBeforeSyncFails) {
-  EXPECT_TRUE(RegisterServiceWorker());
-  EXPECT_TRUE(LoadTestPage(kDefaultTestURL));  // Control the page.
-
-  SetOnline(true);
-  EXPECT_TRUE(RegisterOneShot("delay"));
-  EXPECT_FALSE(OneShotPending("delay"));
-  EXPECT_TRUE(NotifyWhenFinishedOneShot("delay"));
-
-  EXPECT_TRUE(RejectDelayedOneShot());
-  // The ordering of PopConsole messages tells us that the event fired
-  // before finished resolved.
-  EXPECT_TRUE(PopConsole("ok - delay rejected"));
-  EXPECT_TRUE(PopConsole("delay finished result: false"));
-}
-
-IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest,
-                       CallFinishedAfterSyncSucceeds) {
-  EXPECT_TRUE(RegisterServiceWorker());
-  EXPECT_TRUE(LoadTestPage(kDefaultTestURL));  // Control the page.
-
-  SetOnline(false);
-  EXPECT_TRUE(RegisterOneShot("foo"));
-  EXPECT_TRUE(StoreRegistrationOneShot("foo"));
-
-  SetOnline(true);
-  EXPECT_TRUE(PopConsole("foo fired"));
-  EXPECT_FALSE(GetRegistrationOneShot("foo"));
-  EXPECT_TRUE(NotifyWhenFinishedImmediateOneShot("ok - foo result: true"));
-}
-
-IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest,
-                       CallFinishedAfterSyncUnregistered) {
-  EXPECT_TRUE(RegisterServiceWorker());
-  EXPECT_TRUE(LoadTestPage(kDefaultTestURL));  // Control the page.
-
-  SetOnline(false);
-  EXPECT_TRUE(RegisterOneShot("foo"));
-  EXPECT_TRUE(StoreRegistrationOneShot("foo"));
-  EXPECT_TRUE(UnregisterOneShot("foo"));
-  EXPECT_FALSE(GetRegistrationOneShot("foo"));
-  EXPECT_TRUE(NotifyWhenFinishedImmediateOneShot("ok - foo result: false"));
-}
-
-IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, CallFinishedAfterSyncFails) {
-  EXPECT_TRUE(RegisterServiceWorker());
-  EXPECT_TRUE(LoadTestPage(kDefaultTestURL));  // Control the page.
-
-  SetOnline(true);
-  EXPECT_TRUE(RegisterOneShot("delay"));
-  EXPECT_FALSE(OneShotPending("delay"));
-  EXPECT_TRUE(StoreRegistrationOneShot("delay"));
-
-  EXPECT_TRUE(RejectDelayedOneShot());
-  EXPECT_TRUE(PopConsole("ok - delay rejected"));
-  EXPECT_TRUE(NotifyWhenFinishedImmediateOneShot("ok - delay result: false"));
-}
-
 // Verify that a background sync registration is deleted when site data is
 // cleared.
 IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest,
diff --git a/content/browser/bluetooth/bluetooth_dispatcher_host.cc b/content/browser/bluetooth/bluetooth_dispatcher_host.cc
index d310f111..dfeeaa6 100644
--- a/content/browser/bluetooth/bluetooth_dispatcher_host.cc
+++ b/content/browser/bluetooth/bluetooth_dispatcher_host.cc
@@ -1219,8 +1219,8 @@
   // compilers may evaluate arguments in any order.
   const std::string characteristic_instance_id =
       notify_session->GetCharacteristicIdentifier();
-  characteristic_id_to_notify_session_.insert(characteristic_instance_id,
-                                              notify_session.Pass());
+  characteristic_id_to_notify_session_.insert(
+      std::make_pair(characteristic_instance_id, notify_session.Pass()));
 
   Send(new BluetoothMsg_StartNotificationsSuccess(thread_id, request_id));
 }
diff --git a/content/browser/bluetooth/bluetooth_dispatcher_host.h b/content/browser/bluetooth/bluetooth_dispatcher_host.h
index 5fe1f90..a7f06bae 100644
--- a/content/browser/bluetooth/bluetooth_dispatcher_host.h
+++ b/content/browser/bluetooth/bluetooth_dispatcher_host.h
@@ -5,8 +5,9 @@
 #ifndef CONTENT_BROWSER_BLUETOOTH_BLUETOOTH_DISPATCHER_HOST_H_
 #define CONTENT_BROWSER_BLUETOOTH_BLUETOOTH_DISPATCHER_HOST_H_
 
+#include <map>
+
 #include "base/basictypes.h"
-#include "base/containers/scoped_ptr_map.h"
 #include "base/id_map.h"
 #include "base/memory/scoped_vector.h"
 #include "base/memory/weak_ptr.h"
@@ -257,8 +258,7 @@
   // Map that matches characteristic_instance_id to notify session.
   // TODO(ortuno): Also key by thread_id once support for web workers,
   // is added: http://crbug.com/537372
-  base::ScopedPtrMap<std::string,
-                     scoped_ptr<device::BluetoothGattNotifySession>>
+  std::map<std::string, scoped_ptr<device::BluetoothGattNotifySession>>
       characteristic_id_to_notify_session_;
 
   // Map of characteristic_instance_id to a set of thread ids.
diff --git a/content/browser/frame_host/navigation_handle_impl.cc b/content/browser/frame_host/navigation_handle_impl.cc
index 7ffc6b4..1330c8e6 100644
--- a/content/browser/frame_host/navigation_handle_impl.cc
+++ b/content/browser/frame_host/navigation_handle_impl.cc
@@ -99,6 +99,10 @@
   return frame_tree_node_->IsMainFrame();
 }
 
+const base::TimeTicks& NavigationHandleImpl::NavigationStart() {
+  return navigation_start_;
+}
+
 bool NavigationHandleImpl::IsPost() {
   CHECK_NE(INITIAL, state_)
       << "This accessor should not be called before the request is started.";
diff --git a/content/browser/frame_host/navigation_handle_impl.h b/content/browser/frame_host/navigation_handle_impl.h
index b0a7b9a..004cf82 100644
--- a/content/browser/frame_host/navigation_handle_impl.h
+++ b/content/browser/frame_host/navigation_handle_impl.h
@@ -70,6 +70,7 @@
   // NavigationHandle implementation:
   const GURL& GetURL() override;
   bool IsInMainFrame() override;
+  const base::TimeTicks& NavigationStart() override;
   bool IsPost() override;
   const Referrer& GetReferrer() override;
   bool HasUserGesture() override;
@@ -95,11 +96,6 @@
       const GURL& new_referrer_url,
       bool new_is_external_protocol) override;
 
-  // The time the navigation started, recorded either in the renderer or browser
-  // process. Corresponds to Navigation Timing API.
-  // TODO(csharrison): Add this to the public class and mark this override.
-  const base::TimeTicks& navigation_start() { return navigation_start_; }
-
   NavigatorDelegate* GetDelegate() const;
 
   void set_net_error_code(net::Error net_error_code) {
diff --git a/content/browser/presentation/presentation_service_impl.cc b/content/browser/presentation/presentation_service_impl.cc
index 5d20a31..82abc8b 100644
--- a/content/browser/presentation/presentation_service_impl.cc
+++ b/content/browser/presentation/presentation_service_impl.cc
@@ -200,7 +200,7 @@
       render_process_id_,
       render_frame_id_,
       listener.get())) {
-    screen_availability_listeners_.set(availability_url, listener.Pass());
+    screen_availability_listeners_[availability_url] = listener.Pass();
   } else {
     DVLOG(1) << "AddScreenAvailabilityListener failed. Ignoring request.";
   }
@@ -218,9 +218,7 @@
     return;
 
   delegate_->RemoveScreenAvailabilityListener(
-      render_process_id_,
-      render_frame_id_,
-      listener_it->second);
+      render_process_id_, render_frame_id_, listener_it->second.get());
   screen_availability_listeners_.erase(listener_it);
 }
 
diff --git a/content/browser/presentation/presentation_service_impl.h b/content/browser/presentation/presentation_service_impl.h
index 6d48b7a..bbbfb58 100644
--- a/content/browser/presentation/presentation_service_impl.h
+++ b/content/browser/presentation/presentation_service_impl.h
@@ -12,7 +12,6 @@
 #include "base/basictypes.h"
 #include "base/compiler_specific.h"
 #include "base/containers/hash_tables.h"
-#include "base/containers/scoped_ptr_map.h"
 #include "base/gtest_prod_util.h"
 #include "base/macros.h"
 #include "base/memory/linked_ptr.h"
@@ -252,7 +251,7 @@
   std::string default_presentation_url_;
 
   using ScreenAvailabilityListenerMap =
-    base::ScopedPtrMap<std::string, scoped_ptr<ScreenAvailabilityListenerImpl>>;
+      std::map<std::string, scoped_ptr<ScreenAvailabilityListenerImpl>>;
   ScreenAvailabilityListenerMap screen_availability_listeners_;
 
   // For StartSession requests.
diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc
index 950d1cde..3f2ee640 100644
--- a/content/browser/renderer_host/compositor_impl_android.cc
+++ b/content/browser/renderer_host/compositor_impl_android.cc
@@ -229,6 +229,7 @@
 CompositorImpl::CompositorImpl(CompositorClient* client,
                                gfx::NativeWindow root_window)
     : root_layer_(cc::Layer::Create(Compositor::LayerSettings())),
+      resource_manager_(root_window),
       surface_id_allocator_(GetSurfaceManager() ? CreateSurfaceIdAllocator()
                                                 : nullptr),
       has_transparent_background_(false),
diff --git a/content/child/blob_storage/blob_transport_controller.cc b/content/child/blob_storage/blob_transport_controller.cc
index 42a4263..602860b 100644
--- a/content/child/blob_storage/blob_transport_controller.cc
+++ b/content/child/blob_storage/blob_transport_controller.cc
@@ -49,7 +49,7 @@
     scoped_ptr<BlobConsolidation> consolidation,
     IPC::Sender* sender) {
   BlobConsolidation* consolidation_ptr = consolidation.get();
-  blob_storage_.insert(uuid, consolidation.Pass());
+  blob_storage_.insert(std::make_pair(uuid, consolidation.Pass()));
   std::vector<storage::DataElement> descriptions;
   GetDescriptions(consolidation_ptr, kLargeThresholdBytes, &descriptions);
   // TODO(dmurph): Uncomment when IPC messages are added.
@@ -188,7 +188,7 @@
   if (it == blob_storage_.end())
     return ResponsesStatus::BLOB_NOT_FOUND;
 
-  BlobConsolidation* consolidation = it->second;
+  BlobConsolidation* consolidation = it->second.get();
   const auto& consolidated_items = consolidation->consolidated_items();
 
   // Since we can be writing to the same shared memory handle from multiple
diff --git a/content/child/blob_storage/blob_transport_controller.h b/content/child/blob_storage/blob_transport_controller.h
index 7b5714f..d594c53 100644
--- a/content/child/blob_storage/blob_transport_controller.h
+++ b/content/child/blob_storage/blob_transport_controller.h
@@ -5,10 +5,10 @@
 #ifndef CONTENT_CHILD_BLOB_STORAGE_BLOB_TRANSPORT_CONTROLLER_H_
 #define CONTENT_CHILD_BLOB_STORAGE_BLOB_TRANSPORT_CONTROLLER_H_
 
+#include <map>
 #include <string>
 #include <vector>
 
-#include "base/containers/scoped_ptr_map.h"
 #include "base/gtest_prod_util.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
@@ -114,7 +114,7 @@
 
   void ReleaseBlobConsolidation(const std::string& uuid);
 
-  base::ScopedPtrMap<std::string, scoped_ptr<BlobConsolidation>> blob_storage_;
+  std::map<std::string, scoped_ptr<BlobConsolidation>> blob_storage_;
 
   DISALLOW_COPY_AND_ASSIGN(BlobTransportController);
 };
diff --git a/content/child/blob_storage/blob_transport_controller_unittest.cc b/content/child/blob_storage/blob_transport_controller_unittest.cc
index 0ba23dd..6c5d48f5 100644
--- a/content/child/blob_storage/blob_transport_controller_unittest.cc
+++ b/content/child/blob_storage/blob_transport_controller_unittest.cc
@@ -100,7 +100,8 @@
   consolidation->AddDataItem(CreateData("Hello3"));
   // See the above test for the expected descriptions layout.
 
-  holder->blob_storage_.insert(kBlobUUID, make_scoped_ptr(consolidation));
+  holder->blob_storage_.insert(
+      std::make_pair(kBlobUUID, make_scoped_ptr(consolidation)));
 
   std::vector<BlobItemBytesRequest> requests;
   std::vector<base::SharedMemoryHandle> memory_handles;
@@ -158,7 +159,8 @@
   consolidation->AddDataItem(CreateData("Hello3"));
   // See the above test for the expected descriptions layout.
 
-  holder->blob_storage_.insert(kBlobUUID, make_scoped_ptr(consolidation));
+  holder->blob_storage_.insert(
+      std::make_pair(kBlobUUID, make_scoped_ptr(consolidation)));
 
   std::vector<BlobItemBytesRequest> requests;
   std::vector<base::SharedMemoryHandle> memory_handles;
@@ -224,7 +226,8 @@
   BlobConsolidation* consolidation = new BlobConsolidation();
   consolidation->AddBlobItem(KRefBlobUUID, 10, 10);
 
-  holder->blob_storage_.insert(kBlobUUID, make_scoped_ptr(consolidation));
+  holder->blob_storage_.insert(
+      std::make_pair(kBlobUUID, make_scoped_ptr(consolidation)));
 
   std::vector<BlobItemBytesRequest> requests;
   std::vector<base::SharedMemoryHandle> memory_handles;
diff --git a/content/child/resource_scheduling_filter.cc b/content/child/resource_scheduling_filter.cc
index 6445c00..cad2f7d 100644
--- a/content/child/resource_scheduling_filter.cc
+++ b/content/child/resource_scheduling_filter.cc
@@ -77,7 +77,8 @@
 void ResourceSchedulingFilter::SetRequestIdTaskRunner(
     int id, scoped_ptr<blink::WebTaskRunner> web_task_runner) {
   base::AutoLock lock(request_id_to_task_runner_map_lock_);
-  request_id_to_task_runner_map_.insert(id, web_task_runner.Pass());
+  request_id_to_task_runner_map_.insert(
+      std::make_pair(id, web_task_runner.Pass()));
 }
 
 void ResourceSchedulingFilter::ClearRequestIdTaskRunner(int id) {
diff --git a/content/child/resource_scheduling_filter.h b/content/child/resource_scheduling_filter.h
index fd245592..99526fc 100644
--- a/content/child/resource_scheduling_filter.h
+++ b/content/child/resource_scheduling_filter.h
@@ -8,7 +8,6 @@
 #include <map>
 
 #include "base/containers/hash_tables.h"
-#include "base/containers/scoped_ptr_map.h"
 #include "base/memory/weak_ptr.h"
 #include "base/single_thread_task_runner.h"
 #include "content/common/content_export.h"
@@ -47,8 +46,8 @@
  private:
   ~ResourceSchedulingFilter() override;
 
-  typedef base::ScopedPtrMap<int, scoped_ptr<blink::WebTaskRunner>>
-      RequestIdToTaskRunnerMap;
+  using RequestIdToTaskRunnerMap =
+      std::map<int, scoped_ptr<blink::WebTaskRunner>>;
 
   // This lock guards |request_id_to_task_runner_map_|
   base::Lock request_id_to_task_runner_map_lock_;
diff --git a/content/common/gpu/media/vt_video_decode_accelerator.cc b/content/common/gpu/media/vt_video_decode_accelerator.cc
index 2947fe1..35e2753 100644
--- a/content/common/gpu/media/vt_video_decode_accelerator.cc
+++ b/content/common/gpu/media/vt_video_decode_accelerator.cc
@@ -829,9 +829,10 @@
     DCHECK(!picture_info_map_.count(picture.id()));
     assigned_picture_ids_.insert(picture.id());
     available_picture_ids_.push_back(picture.id());
-    picture_info_map_.insert(picture.id(), make_scoped_ptr(new PictureInfo(
-                                               picture.internal_texture_id(),
-                                               picture.texture_id())));
+    picture_info_map_.insert(std::make_pair(
+        picture.id(),
+        make_scoped_ptr(new PictureInfo(picture.internal_texture_id(),
+                                        picture.texture_id()))));
   }
 
   // Pictures are not marked as uncleared until after this method returns, and
@@ -844,7 +845,7 @@
 void VTVideoDecodeAccelerator::ReusePictureBuffer(int32_t picture_id) {
   DCHECK(gpu_thread_checker_.CalledOnValidThread());
   DCHECK(picture_info_map_.count(picture_id));
-  PictureInfo* picture_info = picture_info_map_.find(picture_id)->second;
+  PictureInfo* picture_info = picture_info_map_.find(picture_id)->second.get();
   DCHECK_EQ(CFGetRetainCount(picture_info->cv_image), 1);
   picture_info->cv_image.reset();
   picture_info->gl_image->Destroy(false);
@@ -1009,7 +1010,7 @@
 
   int32_t picture_id = available_picture_ids_.back();
   DCHECK(picture_info_map_.count(picture_id));
-  PictureInfo* picture_info = picture_info_map_.find(picture_id)->second;
+  PictureInfo* picture_info = picture_info_map_.find(picture_id)->second.get();
   DCHECK(!picture_info->cv_image);
   DCHECK(!picture_info->gl_image);
 
diff --git a/content/common/gpu/media/vt_video_decode_accelerator.h b/content/common/gpu/media/vt_video_decode_accelerator.h
index c728968..9f55327 100644
--- a/content/common/gpu/media/vt_video_decode_accelerator.h
+++ b/content/common/gpu/media/vt_video_decode_accelerator.h
@@ -10,7 +10,6 @@
 #include <map>
 #include <queue>
 
-#include "base/containers/scoped_ptr_map.h"
 #include "base/mac/scoped_cftyperef.h"
 #include "base/memory/linked_ptr.h"
 #include "base/memory/weak_ptr.h"
@@ -226,7 +225,7 @@
   std::set<int32_t> assigned_picture_ids_;
 
   // Texture IDs and image buffers of assigned pictures.
-  base::ScopedPtrMap<int32_t, scoped_ptr<PictureInfo>> picture_info_map_;
+  std::map<int32_t, scoped_ptr<PictureInfo>> picture_info_map_;
 
   // Pictures ready to be rendered to.
   std::vector<int32_t> available_picture_ids_;
diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi
index 6fc80be..adc6ba0 100644
--- a/content/content_renderer.gypi
+++ b/content/content_renderer.gypi
@@ -628,6 +628,8 @@
     'private_renderer_webrtc_sources': [
       'renderer/media/audio_repetition_detector.cc',
       'renderer/media/audio_repetition_detector.h',
+      'renderer/media/audio_track_recorder.cc',
+      'renderer/media/audio_track_recorder.h',
       'renderer/media/media_recorder_handler.cc',
       'renderer/media/media_recorder_handler.h',
       'renderer/media/media_stream.cc',
@@ -800,6 +802,8 @@
     ['OS=="android"', {
       'sources!': [
         'renderer/media/audio_decoder.cc',
+        'renderer/media/audio_track_recorder.cc',
+        'renderer/media/audio_track_recorder.h',
         'renderer/media/media_recorder_handler.cc',
         'renderer/media/media_recorder_handler.h',
         'renderer/media/video_track_recorder.cc',
diff --git a/content/content_tests.gypi b/content/content_tests.gypi
index 64d2110..7895b59e 100644
--- a/content/content_tests.gypi
+++ b/content/content_tests.gypi
@@ -749,6 +749,7 @@
       'browser/renderer_host/p2p/socket_host_udp_unittest.cc',
       'browser/renderer_host/p2p/socket_host_unittest.cc',
       'renderer/media/audio_repetition_detector_unittest.cc',
+      'renderer/media/audio_track_recorder_unittest.cc',
       'renderer/media/media_recorder_handler_unittest.cc',
       'renderer/media/media_stream_audio_processor_unittest.cc',
       'renderer/media/media_stream_constraints_util_unittest.cc',
@@ -1249,6 +1250,7 @@
                 'browser/power_usage_monitor_impl_unittest.cc',
                 'browser/renderer_host/begin_frame_observer_proxy_unittest.cc',
                 'browser/webui/url_data_manager_backend_unittest.cc',
+                'renderer/media/audio_track_recorder_unittest.cc',
                 'renderer/media/media_recorder_handler_unittest.cc',
                 'renderer/media/video_track_recorder_unittest.cc',
               ],
diff --git a/content/public/browser/navigation_handle.h b/content/public/browser/navigation_handle.h
index 3b2bbadd..cc96381 100644
--- a/content/public/browser/navigation_handle.h
+++ b/content/public/browser/navigation_handle.h
@@ -39,6 +39,10 @@
   // The WebContents the navigation is taking place in.
   WebContents* GetWebContents();
 
+  // The time the navigation started, recorded either in the renderer or in the
+  // browser process. Corresponds to Navigation Timing API.
+  virtual const base::TimeTicks& NavigationStart() = 0;
+
   // Parameters available at network request start time ------------------------
   //
   // The following parameters are only available when the network request is
diff --git a/content/renderer/media/DEPS b/content/renderer/media/DEPS
index 19fad4be..c7f6f64 100644
--- a/content/renderer/media/DEPS
+++ b/content/renderer/media/DEPS
@@ -3,5 +3,6 @@
   # For video copying, cropping and scaling.
   # TODO(wuchengli): remove this when RTCVideoEncoder supports zero copy.
   "+third_party/libyuv",
+  '+third_party/opus',
   '+third_party/webrtc_overrides',
 ]
diff --git a/content/renderer/media/audio_track_recorder.cc b/content/renderer/media/audio_track_recorder.cc
new file mode 100644
index 0000000..006bcf3
--- /dev/null
+++ b/content/renderer/media/audio_track_recorder.cc
@@ -0,0 +1,312 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/media/audio_track_recorder.h"
+
+#include "base/bind.h"
+#include "base/stl_util.h"
+#include "media/audio/audio_parameters.h"
+#include "media/base/audio_bus.h"
+#include "media/base/bind_to_current_loop.h"
+#include "third_party/opus/src/include/opus.h"
+
+// Note that this code follows the Chrome media convention of defining a "frame"
+// as "one multi-channel sample" as opposed to another common definition
+// meaning "a chunk of samples". Here this second definition of "frame" is
+// called a "buffer"; so what might be called "frame duration" is instead
+// "buffer duration", and so on.
+
+namespace content {
+
+namespace {
+
+enum {
+  // This is the recommended value, according to documentation in
+  // third_party/opus/src/include/opus.h, so that the Opus encoder does not
+  // degrade the audio due to memory constraints.
+  OPUS_MAX_PAYLOAD_SIZE = 4000,
+
+  // Support for max sampling rate of 48KHz, 2 channels, 60 ms duration.
+  MAX_SAMPLES_PER_BUFFER = 48 * 2 * 60,
+};
+
+}  // anonymous namespace
+
+// Nested class encapsulating opus-related encoding details.
+// AudioEncoder is created and destroyed on ATR's main thread (usually the
+// main render thread) but otherwise should operate entirely on
+// |encoder_thread_|, which is owned by AudioTrackRecorder. Be sure to delete
+// |encoder_thread_| before deleting the AudioEncoder using it.
+class AudioTrackRecorder::AudioEncoder
+    : public base::RefCountedThreadSafe<AudioEncoder> {
+ public:
+  explicit AudioEncoder(const OnEncodedAudioCB& on_encoded_audio_cb)
+      : on_encoded_audio_cb_(on_encoded_audio_cb), opus_encoder_(nullptr) {
+    // AudioEncoder is constructed on the thread that ATR lives on, but should
+    // operate only on the encoder thread after that. Reset
+    // |encoder_thread_checker_| here, as the next call to CalledOnValidThread()
+    // will be from the encoder thread.
+    encoder_thread_checker_.DetachFromThread();
+  }
+
+  void OnSetFormat(const media::AudioParameters& params);
+
+  void EncodeAudio(scoped_ptr<media::AudioBus> audio_bus,
+                   const base::TimeTicks& capture_time);
+
+ private:
+  friend class base::RefCountedThreadSafe<AudioEncoder>;
+
+  ~AudioEncoder();
+
+  bool is_initialized() const { return !!opus_encoder_; }
+
+  void DestroyExistingOpusEncoder();
+
+  void TransferSamplesIntoBuffer(const media::AudioBus* audio_bus,
+                                 int source_offset,
+                                 int buffer_fill_offset,
+                                 int num_samples);
+  bool EncodeFromFilledBuffer(std::string* out);
+
+  const OnEncodedAudioCB on_encoded_audio_cb_;
+
+  base::ThreadChecker encoder_thread_checker_;
+
+  // In the case where a call to EncodeAudio() cannot completely fill the
+  // buffer, this points to the position at which to populate data in a later
+  // call.
+  int buffer_fill_end_;
+
+  int frames_per_buffer_;
+
+  // The duration of one set of frames of encoded audio samples.
+  base::TimeDelta buffer_duration_;
+
+  media::AudioParameters audio_params_;
+
+  // Buffer for passing AudioBus data to OpusEncoder.
+  scoped_ptr<float[]> buffer_;
+
+  OpusEncoder* opus_encoder_;
+
+  DISALLOW_COPY_AND_ASSIGN(AudioEncoder);
+};
+
+AudioTrackRecorder::AudioEncoder::~AudioEncoder() {
+  // We don't DCHECK that we're on the encoder thread here, as it should have
+  // already been deleted at this point.
+  DestroyExistingOpusEncoder();
+}
+
+void AudioTrackRecorder::AudioEncoder::OnSetFormat(
+    const media::AudioParameters& params) {
+  DCHECK(encoder_thread_checker_.CalledOnValidThread());
+  if (audio_params_.Equals(params))
+    return;
+
+  DestroyExistingOpusEncoder();
+
+  if (!params.IsValid()) {
+    DLOG(ERROR) << "Invalid audio params: " << params.AsHumanReadableString();
+    return;
+  }
+
+  buffer_duration_ = base::TimeDelta::FromMilliseconds(
+      AudioTrackRecorder::GetOpusBufferDuration(params.sample_rate()));
+  if (buffer_duration_ == base::TimeDelta()) {
+    DLOG(ERROR) << "Could not find a valid |buffer_duration| for the given "
+                << "sample rate: " << params.sample_rate();
+    return;
+  }
+
+  frames_per_buffer_ =
+      params.sample_rate() * buffer_duration_.InMilliseconds() / 1000;
+  if (frames_per_buffer_ * params.channels() > MAX_SAMPLES_PER_BUFFER) {
+    DLOG(ERROR) << "Invalid |frames_per_buffer_|: " << frames_per_buffer_;
+    return;
+  }
+
+  // Initialize AudioBus buffer for OpusEncoder.
+  buffer_fill_end_ = 0;
+  buffer_.reset(new float[params.channels() * frames_per_buffer_]);
+
+  // Initialize OpusEncoder.
+  int opus_result;
+  opus_encoder_ = opus_encoder_create(params.sample_rate(), params.channels(),
+                                      OPUS_APPLICATION_AUDIO, &opus_result);
+  if (opus_result < 0) {
+    DLOG(ERROR) << "Couldn't init opus encoder: " << opus_strerror(opus_result);
+    return;
+  }
+
+  // Note: As of 2013-10-31, the encoder in "auto bitrate" mode would use a
+  // variable bitrate up to 102kbps for 2-channel, 48 kHz audio and a 10 ms
+  // buffer duration. The opus library authors may, of course, adjust this in
+  // later versions.
+  if (opus_encoder_ctl(opus_encoder_, OPUS_SET_BITRATE(OPUS_AUTO)) != OPUS_OK) {
+    DLOG(ERROR) << "Failed to set opus bitrate.";
+    return;
+  }
+
+  audio_params_ = params;
+}
+
+void AudioTrackRecorder::AudioEncoder::EncodeAudio(
+    scoped_ptr<media::AudioBus> audio_bus,
+    const base::TimeTicks& capture_time) {
+  DCHECK(encoder_thread_checker_.CalledOnValidThread());
+  DCHECK_EQ(audio_bus->channels(), audio_params_.channels());
+
+  if (!is_initialized())
+    return;
+
+  base::TimeDelta buffer_fill_duration =
+      buffer_fill_end_ * buffer_duration_ / frames_per_buffer_;
+  base::TimeTicks buffer_capture_time = capture_time - buffer_fill_duration;
+
+  // Encode all audio in |audio_bus| into zero or more packets.
+  int src_pos = 0;
+  while (src_pos < audio_bus->frames()) {
+    const int num_samples_to_xfer = std::min(
+        frames_per_buffer_ - buffer_fill_end_, audio_bus->frames() - src_pos);
+    TransferSamplesIntoBuffer(audio_bus.get(), src_pos, buffer_fill_end_,
+                              num_samples_to_xfer);
+    src_pos += num_samples_to_xfer;
+    buffer_fill_end_ += num_samples_to_xfer;
+
+    if (buffer_fill_end_ < frames_per_buffer_)
+      break;
+
+    scoped_ptr<std::string> encoded_data(new std::string());
+    if (EncodeFromFilledBuffer(encoded_data.get())) {
+      on_encoded_audio_cb_.Run(audio_params_, encoded_data.Pass(),
+                               buffer_capture_time);
+    }
+
+    // Reset the capture timestamp and internal buffer for next set of frames.
+    buffer_capture_time += buffer_duration_;
+    buffer_fill_end_ = 0;
+  }
+}
+
+void AudioTrackRecorder::AudioEncoder::DestroyExistingOpusEncoder() {
+  // We don't DCHECK that we're on the encoder thread here, as this could be
+  // called from the dtor (main thread) or from OnSetForamt() (render thread);
+  if (opus_encoder_) {
+    opus_encoder_destroy(opus_encoder_);
+    opus_encoder_ = nullptr;
+  }
+}
+
+void AudioTrackRecorder::AudioEncoder::TransferSamplesIntoBuffer(
+    const media::AudioBus* audio_bus,
+    int source_offset,
+    int buffer_fill_offset,
+    int num_samples) {
+  // TODO(ajose): Consider replacing with AudioBus::ToInterleaved().
+  // http://crbug.com/547918
+  DCHECK(encoder_thread_checker_.CalledOnValidThread());
+  DCHECK(is_initialized());
+  // Opus requires channel-interleaved samples in a single array.
+  for (int ch = 0; ch < audio_bus->channels(); ++ch) {
+    const float* src = audio_bus->channel(ch) + source_offset;
+    const float* const src_end = src + num_samples;
+    float* dest =
+        buffer_.get() + buffer_fill_offset * audio_params_.channels() + ch;
+    for (; src < src_end; ++src, dest += audio_params_.channels())
+      *dest = *src;
+  }
+}
+
+bool AudioTrackRecorder::AudioEncoder::EncodeFromFilledBuffer(
+    std::string* out) {
+  DCHECK(encoder_thread_checker_.CalledOnValidThread());
+  DCHECK(is_initialized());
+
+  out->resize(OPUS_MAX_PAYLOAD_SIZE);
+  const opus_int32 result = opus_encode_float(
+      opus_encoder_, buffer_.get(), frames_per_buffer_,
+      reinterpret_cast<uint8*>(string_as_array(out)), OPUS_MAX_PAYLOAD_SIZE);
+  if (result > 1) {
+    // TODO(ajose): Investigate improving this. http://crbug.com/547918
+    out->resize(result);
+    return true;
+  }
+  // If |result| in {0,1}, do nothing; the documentation says that a return
+  // value of zero or one means the packet does not need to be transmitted.
+  // Otherwise, we have an error.
+  DLOG_IF(ERROR, result < 0) << __FUNCTION__
+                             << " failed: " << opus_strerror(result);
+  return false;
+}
+
+AudioTrackRecorder::AudioTrackRecorder(
+    const blink::WebMediaStreamTrack& track,
+    const OnEncodedAudioCB& on_encoded_audio_cb)
+    : track_(track),
+      encoder_(new AudioEncoder(media::BindToCurrentLoop(on_encoded_audio_cb))),
+      encoder_thread_("AudioEncoderThread") {
+  DCHECK(main_render_thread_checker_.CalledOnValidThread());
+  DCHECK(!track_.isNull());
+  DCHECK(track_.extraData());
+
+  // Start the |encoder_thread_|. From this point on, |encoder_| should work
+  // only on |encoder_thread_|, as enforced by DCHECKs.
+  DCHECK(!encoder_thread_.IsRunning());
+  encoder_thread_.Start();
+
+  // Connect the source provider to the track as a sink.
+  MediaStreamAudioSink::AddToAudioTrack(this, track_);
+}
+
+AudioTrackRecorder::~AudioTrackRecorder() {
+  DCHECK(main_render_thread_checker_.CalledOnValidThread());
+  MediaStreamAudioSink::RemoveFromAudioTrack(this, track_);
+}
+
+void AudioTrackRecorder::OnSetFormat(const media::AudioParameters& params) {
+  DCHECK(encoder_thread_.IsRunning());
+  // If the source is restarted, might have changed to another capture thread.
+  capture_thread_checker_.DetachFromThread();
+  DCHECK(capture_thread_checker_.CalledOnValidThread());
+
+  encoder_thread_.task_runner()->PostTask(
+      FROM_HERE, base::Bind(&AudioEncoder::OnSetFormat, encoder_, params));
+}
+
+void AudioTrackRecorder::OnData(const media::AudioBus& audio_bus,
+                                base::TimeTicks capture_time) {
+  DCHECK(encoder_thread_.IsRunning());
+  DCHECK(capture_thread_checker_.CalledOnValidThread());
+  DCHECK(!capture_time.is_null());
+
+  scoped_ptr<media::AudioBus> audio_data =
+      media::AudioBus::Create(audio_bus.channels(), audio_bus.frames());
+  audio_bus.CopyTo(audio_data.get());
+
+  encoder_thread_.task_runner()->PostTask(
+      FROM_HERE, base::Bind(&AudioEncoder::EncodeAudio, encoder_,
+                            base::Passed(&audio_data), capture_time));
+}
+
+int AudioTrackRecorder::GetOpusBufferDuration(int sample_rate) {
+  // Valid buffer durations in millseconds. Note there are other valid
+  // durations for Opus, see https://tools.ietf.org/html/rfc6716#section-2.1.4
+  // Descending order as longer durations can increase compression performance.
+  const std::vector<int> opus_valid_buffer_durations_ms = {60, 40, 20, 10};
+
+  // Search for a duration such that |sample_rate| % |buffers_per_second| == 0,
+  // where |buffers_per_second| = 1000ms / |possible_duration|.
+  for (auto possible_duration : opus_valid_buffer_durations_ms) {
+    if (sample_rate * possible_duration % 1000 == 0) {
+      return possible_duration;
+    }
+  }
+
+  // Otherwise, couldn't find a good duration.
+  return 0;
+}
+
+}  // namespace content
diff --git a/content/renderer/media/audio_track_recorder.h b/content/renderer/media/audio_track_recorder.h
new file mode 100644
index 0000000..353331c
--- /dev/null
+++ b/content/renderer/media/audio_track_recorder.h
@@ -0,0 +1,85 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_MEDIA_AUDIO_TRACK_RECORDER_H_
+#define CONTENT_RENDERER_MEDIA_AUDIO_TRACK_RECORDER_H_
+
+#include "base/callback.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/threading/thread.h"
+#include "base/threading/thread_checker.h"
+#include "base/time/time.h"
+#include "content/public/renderer/media_stream_audio_sink.h"
+#include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
+
+namespace media {
+class AudioBus;
+}  // namespace media
+
+namespace content {
+
+// AudioTrackRecorder is a MediaStreamAudioSink that encodes the audio buses
+// received from a Stream Audio Track. The class is constructed on a
+// single thread (the main Render thread) but can recieve MediaStreamAudioSink-
+// related calls on a different "live audio" thread (referred to internally as
+// the "capture thread"). It owns an internal thread to use for encoding, on
+// which lives an AudioEncoder (a private nested class of ATR) with its own
+// threading subtleties, see the implementation file.
+class CONTENT_EXPORT AudioTrackRecorder
+    : NON_EXPORTED_BASE(public MediaStreamAudioSink) {
+ public:
+  using OnEncodedAudioCB =
+      base::Callback<void(const media::AudioParameters& params,
+                          scoped_ptr<std::string> encoded_data,
+                          base::TimeTicks capture_time)>;
+
+  AudioTrackRecorder(const blink::WebMediaStreamTrack& track,
+                     const OnEncodedAudioCB& on_encoded_audio_cb);
+  ~AudioTrackRecorder() override;
+
+  // Implement MediaStreamAudioSink.
+  void OnSetFormat(const media::AudioParameters& params) override;
+  void OnData(const media::AudioBus& audio_bus,
+              base::TimeTicks capture_time) override;
+
+ private:
+  friend class AudioTrackRecorderTest;
+  class AudioParameters;
+
+  // Forward declaration of nested class for handling encoding.
+  // See the implementation file for details.
+  class AudioEncoder;
+
+  // Returns the Opus buffer duration in milliseconds, or zero if none will work
+  // for the given |sample_rate|.
+  static int GetOpusBufferDuration(int sample_rate);
+
+  // Used to check that we are destroyed on the same thread we were created on.
+  base::ThreadChecker main_render_thread_checker_;
+
+  // Used to check that MediaStreamAudioSink's methods are called on the
+  // capture audio thread.
+  base::ThreadChecker capture_thread_checker_;
+
+  // We need to hold on to the Blink track to remove ourselves on destruction.
+  const blink::WebMediaStreamTrack track_;
+
+  // Thin wrapper around OpusEncoder.
+  // |encoder_| should be initialized before |encoder_thread_| such that
+  // |encoder_thread_| is destructed first. This, combined with all
+  // AudioEncoder work (aside from construction and destruction) happening on
+  // |encoder_thread_|, should allow us to be sure that all AudioEncoder work is
+  // done by the time we destroy it on ATR's thread.
+  const scoped_refptr<AudioEncoder> encoder_;
+  // The thread on which |encoder_| works.
+  base::Thread encoder_thread_;
+
+  DISALLOW_COPY_AND_ASSIGN(AudioTrackRecorder);
+};
+
+}  // namespace content
+
+#endif  // CONTENT_RENDERER_MEDIA_AUDIO_TRACK_RECORDER_H_
diff --git a/content/renderer/media/audio_track_recorder_unittest.cc b/content/renderer/media/audio_track_recorder_unittest.cc
new file mode 100644
index 0000000..1966464
--- /dev/null
+++ b/content/renderer/media/audio_track_recorder_unittest.cc
@@ -0,0 +1,253 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/media/audio_track_recorder.h"
+
+#include "base/run_loop.h"
+#include "base/stl_util.h"
+#include "base/strings/utf_string_conversions.h"
+#include "content/renderer/media/media_stream_audio_source.h"
+#include "content/renderer/media/mock_media_constraint_factory.h"
+#include "content/renderer/media/webrtc/webrtc_local_audio_track_adapter.h"
+#include "content/renderer/media/webrtc_local_audio_track.h"
+#include "media/audio/simple_sources.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/public/web/WebHeap.h"
+#include "third_party/opus/src/include/opus.h"
+
+using ::testing::_;
+using ::testing::DoAll;
+using ::testing::InSequence;
+using ::testing::Mock;
+using ::testing::Return;
+using ::testing::SaveArg;
+using ::testing::TestWithParam;
+using ::testing::ValuesIn;
+
+namespace {
+
+// Input audio format.
+const media::AudioParameters::Format kDefaultInputFormat =
+    media::AudioParameters::AUDIO_PCM_LOW_LATENCY;
+const int kDefaultBitsPerSample = 16;
+const int kDefaultSampleRate = 48000;
+// The |frames_per_buffer| field of AudioParameters is not used by ATR.
+const int kIgnoreFramesPerBuffer = 1;
+const int kOpusMaxBufferDurationMS = 120;
+
+}  // namespace
+
+namespace content {
+
+ACTION_P(RunClosure, closure) {
+  closure.Run();
+}
+
+struct ATRTestParams {
+  const media::AudioParameters::Format input_format;
+  const media::ChannelLayout channel_layout;
+  const int sample_rate;
+  const int bits_per_sample;
+};
+
+const ATRTestParams kATRTestParams[] = {
+    // Equivalent to default settings:
+    {media::AudioParameters::AUDIO_PCM_LOW_LATENCY, /* input format */
+     media::CHANNEL_LAYOUT_STEREO,                  /* channel layout */
+     kDefaultSampleRate,                            /* sample rate */
+     kDefaultBitsPerSample},                        /* bits per sample */
+    // Change to mono:
+    {media::AudioParameters::AUDIO_PCM_LOW_LATENCY, media::CHANNEL_LAYOUT_MONO,
+     kDefaultSampleRate, kDefaultBitsPerSample},
+    // Different sampling rate as well:
+    {media::AudioParameters::AUDIO_PCM_LOW_LATENCY, media::CHANNEL_LAYOUT_MONO,
+     24000, kDefaultBitsPerSample},
+    {media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
+     media::CHANNEL_LAYOUT_STEREO, 8000, kDefaultBitsPerSample},
+};
+
+class AudioTrackRecorderTest : public TestWithParam<ATRTestParams> {
+ public:
+  // Initialize |first_params_| based on test parameters, and |second_params_|
+  // to always be the same thing.
+  AudioTrackRecorderTest()
+      : first_params_(GetParam().input_format,
+                      GetParam().channel_layout,
+                      GetParam().sample_rate,
+                      GetParam().bits_per_sample,
+                      kIgnoreFramesPerBuffer),
+        second_params_(kDefaultInputFormat,
+                       media::CHANNEL_LAYOUT_STEREO,
+                       kDefaultSampleRate,
+                       kDefaultBitsPerSample,
+                       kIgnoreFramesPerBuffer),
+        first_source_(first_params_.channels(),     /* # channels */
+                      440,                          /* frequency */
+                      first_params_.sample_rate()), /* sample rate */
+        second_source_(second_params_.channels(),
+                       440,
+                       second_params_.sample_rate()),
+        opus_decoder_(nullptr) {
+    ResetDecoder(first_params_);
+    PrepareBlinkTrack();
+    audio_track_recorder_.reset(new AudioTrackRecorder(
+        blink_track_, base::Bind(&AudioTrackRecorderTest::OnEncodedAudio,
+                                 base::Unretained(this))));
+  }
+
+  ~AudioTrackRecorderTest() {
+    opus_decoder_destroy(opus_decoder_);
+    opus_decoder_ = nullptr;
+    audio_track_recorder_.reset();
+    blink_track_.reset();
+    blink::WebHeap::collectAllGarbageForTesting();
+  }
+
+  void ResetDecoder(const media::AudioParameters& params) {
+    if (opus_decoder_) {
+      opus_decoder_destroy(opus_decoder_);
+      opus_decoder_ = nullptr;
+    }
+
+    int error;
+    opus_decoder_ =
+        opus_decoder_create(params.sample_rate(), params.channels(), &error);
+    EXPECT_TRUE(error == OPUS_OK && opus_decoder_);
+
+    max_frames_per_buffer_ =
+        kOpusMaxBufferDurationMS * params.sample_rate() / 1000;
+    buffer_.reset(new float[max_frames_per_buffer_ * params.channels()]);
+  }
+
+  scoped_ptr<media::AudioBus> GetFirstSourceAudioBus() {
+    scoped_ptr<media::AudioBus> bus(media::AudioBus::Create(
+        first_params_.channels(),
+        first_params_.sample_rate() *
+            audio_track_recorder_->GetOpusBufferDuration(
+                first_params_.sample_rate()) /
+            1000));
+    first_source_.OnMoreData(bus.get(), 0);
+    return bus.Pass();
+  }
+  scoped_ptr<media::AudioBus> GetSecondSourceAudioBus() {
+    scoped_ptr<media::AudioBus> bus(media::AudioBus::Create(
+        second_params_.channels(),
+        second_params_.sample_rate() *
+            audio_track_recorder_->GetOpusBufferDuration(
+                second_params_.sample_rate()) /
+            1000));
+    second_source_.OnMoreData(bus.get(), 0);
+    return bus.Pass();
+  }
+
+  MOCK_METHOD3(DoOnEncodedAudio,
+               void(const media::AudioParameters& params,
+                    std::string encoded_data,
+                    base::TimeTicks timestamp));
+
+  void OnEncodedAudio(const media::AudioParameters& params,
+                      scoped_ptr<std::string> encoded_data,
+                      base::TimeTicks timestamp) {
+    EXPECT_TRUE(!encoded_data->empty());
+
+    // Decode |encoded_data| and check we get the expected number of frames
+    // per buffer.
+    EXPECT_EQ(
+        params.sample_rate() *
+            audio_track_recorder_->GetOpusBufferDuration(params.sample_rate()) /
+            1000,
+        opus_decode_float(
+            opus_decoder_,
+            reinterpret_cast<uint8*>(string_as_array(encoded_data.get())),
+            encoded_data->size(), buffer_.get(), max_frames_per_buffer_, 0));
+
+    DoOnEncodedAudio(params, *encoded_data, timestamp);
+  }
+
+  const base::MessageLoop message_loop_;
+
+  // ATR and WebMediaStreamTrack for fooling it.
+  scoped_ptr<AudioTrackRecorder> audio_track_recorder_;
+  blink::WebMediaStreamTrack blink_track_;
+
+  // Two different sets of AudioParameters for testing re-init of ATR.
+  const media::AudioParameters first_params_;
+  const media::AudioParameters second_params_;
+
+  // AudioSources for creating AudioBuses.
+  media::SineWaveAudioSource first_source_;
+  media::SineWaveAudioSource second_source_;
+
+  // Decoder for verifying data was properly encoded.
+  OpusDecoder* opus_decoder_;
+  int max_frames_per_buffer_;
+  scoped_ptr<float[]> buffer_;
+
+ private:
+  // Prepares a blink track of a given MediaStreamType and attaches the native
+  // track, which can be used to capture audio data and pass it to the producer.
+  // Adapted from media::WebRTCLocalAudioSourceProviderTest.
+  void PrepareBlinkTrack() {
+    MockMediaConstraintFactory constraint_factory;
+    scoped_refptr<WebRtcAudioCapturer> capturer(
+        WebRtcAudioCapturer::CreateCapturer(
+            -1, StreamDeviceInfo(),
+            constraint_factory.CreateWebMediaConstraints(), NULL, NULL));
+    scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter(
+        WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL));
+    scoped_ptr<WebRtcLocalAudioTrack> native_track(
+        new WebRtcLocalAudioTrack(adapter.get(), capturer, NULL));
+    blink::WebMediaStreamSource audio_source;
+    audio_source.initialize(base::UTF8ToUTF16("dummy_source_id"),
+                            blink::WebMediaStreamSource::TypeAudio,
+                            base::UTF8ToUTF16("dummy_source_name"),
+                            false /* remote */, true /* readonly */);
+    blink_track_.initialize(blink::WebString::fromUTF8("audio_track"),
+                            audio_source);
+    blink_track_.setExtraData(native_track.release());
+  }
+
+  DISALLOW_COPY_AND_ASSIGN(AudioTrackRecorderTest);
+};
+
+TEST_P(AudioTrackRecorderTest, OnData) {
+  InSequence s;
+  base::RunLoop run_loop;
+  base::Closure quit_closure = run_loop.QuitClosure();
+
+  // Give ATR initial audio parameters.
+  audio_track_recorder_->OnSetFormat(first_params_);
+  // TODO(ajose): consider adding WillOnce(SaveArg...) and inspecting, as done
+  // in VTR unittests. http://crbug.com/548856
+  const base::TimeTicks time1 = base::TimeTicks::Now();
+  EXPECT_CALL(*this, DoOnEncodedAudio(_, _, time1)).Times(1);
+  audio_track_recorder_->OnData(*GetFirstSourceAudioBus(), time1);
+
+  // Send more audio.
+  const base::TimeTicks time2 = base::TimeTicks::Now();
+  EXPECT_CALL(*this, DoOnEncodedAudio(_, _, _))
+      .Times(1)
+      // Only reset the decoder once we've heard back:
+      .WillOnce(RunClosure(base::Bind(&AudioTrackRecorderTest::ResetDecoder,
+                                      base::Unretained(this), second_params_)));
+  audio_track_recorder_->OnData(*GetFirstSourceAudioBus(), time2);
+
+  // Give ATR new audio parameters.
+  audio_track_recorder_->OnSetFormat(second_params_);
+
+  // Send audio with different params.
+  const base::TimeTicks time3 = base::TimeTicks::Now();
+  EXPECT_CALL(*this, DoOnEncodedAudio(_, _, _))
+      .Times(1)
+      .WillOnce(RunClosure(quit_closure));
+  audio_track_recorder_->OnData(*GetSecondSourceAudioBus(), time3);
+
+  run_loop.Run();
+  Mock::VerifyAndClearExpectations(this);
+}
+
+INSTANTIATE_TEST_CASE_P(, AudioTrackRecorderTest, ValuesIn(kATRTestParams));
+
+}  // namespace content
diff --git a/content/renderer/presentation/presentation_dispatcher.cc b/content/renderer/presentation/presentation_dispatcher.cc
index bcb33fa..4826e5a 100644
--- a/content/renderer/presentation/presentation_dispatcher.cc
+++ b/content/renderer/presentation/presentation_dispatcher.cc
@@ -223,9 +223,9 @@
   auto status_it = availability_status_.find(availability_url);
   if (status_it == availability_status_.end()) {
     status = new AvailabilityStatus(availability_url);
-    availability_status_.set(availability_url, make_scoped_ptr(status));
+    availability_status_[availability_url] = make_scoped_ptr(status);
   } else {
-    status = status_it->second;
+    status = status_it->second.get();
   }
   DCHECK(status);
 
@@ -249,7 +249,7 @@
     return;
   }
   status_it->second->availability_observers.insert(observer);
-  UpdateListeningState(status_it->second);
+  UpdateListeningState(status_it->second.get());
 }
 
 void PresentationDispatcher::stopListening(
@@ -262,7 +262,7 @@
     return;
   }
   status_it->second->availability_observers.erase(observer);
-  UpdateListeningState(status_it->second);
+  UpdateListeningState(status_it->second.get());
 }
 
 void PresentationDispatcher::setDefaultPresentationUrl(
@@ -290,7 +290,7 @@
   auto status_it = availability_status_.find(availability_url);
   if (status_it == availability_status_.end())
     return;
-  AvailabilityStatus* status = status_it->second;
+  AvailabilityStatus* status = status_it->second.get();
   DCHECK(status);
 
   if (status->listening_state == ListeningState::WAITING)
@@ -314,7 +314,7 @@
   auto status_it = availability_status_.find(availability_url);
   if (status_it == availability_status_.end())
     return;
-  AvailabilityStatus* status = status_it->second;
+  AvailabilityStatus* status = status_it->second.get();
   DCHECK(status);
   DCHECK(status->listening_state == ListeningState::WAITING);
 
diff --git a/content/renderer/presentation/presentation_dispatcher.h b/content/renderer/presentation/presentation_dispatcher.h
index c96789c..1bf5559 100644
--- a/content/renderer/presentation/presentation_dispatcher.h
+++ b/content/renderer/presentation/presentation_dispatcher.h
@@ -5,10 +5,10 @@
 #ifndef CONTENT_RENDERER_PRESENTATION_PRESENTATION_DISPATCHER_H_
 #define CONTENT_RENDERER_PRESENTATION_PRESENTATION_DISPATCHER_H_
 
+#include <map>
 #include <queue>
 
 #include "base/compiler_specific.h"
-#include "base/containers/scoped_ptr_map.h"
 #include "base/id_map.h"
 #include "base/memory/linked_ptr.h"
 #include "base/memory/scoped_ptr.h"
@@ -151,9 +151,7 @@
     AvailabilityObserversSet availability_observers;
   };
 
-  using AvailabilityStatusMap =
-    base::ScopedPtrMap<std::string, scoped_ptr<AvailabilityStatus>>;
-  AvailabilityStatusMap availability_status_;
+  std::map<std::string, scoped_ptr<AvailabilityStatus>> availability_status_;
 
   // Updates the listening state of availability for |status| and notifies the
   // client.
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index 503aee2d..c9f5fa0 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -658,6 +658,7 @@
 
     if (is_android) {
       sources -= [
+        "../renderer/media/audio_track_recorder_unittest.cc",
         "../renderer/media/media_recorder_handler_unittest.cc",
         "../renderer/media/video_track_recorder_unittest.cc",
       ]
diff --git a/content/test/data/background_sync/background_sync_test_helpers.js b/content/test/data/background_sync/background_sync_test_helpers.js
index b4cd8b6..7900526 100644
--- a/content/test/data/background_sync/background_sync_test_helpers.js
+++ b/content/test/data/background_sync/background_sync_test_helpers.js
@@ -5,7 +5,6 @@
 'use strict';
 
 var resultQueue = new ResultQueue();
-var registrationReference = null;
 
 // Sends data back to the test. This must be in response to an earlier
 // request, but it's ok to respond asynchronously. The request blocks until
@@ -35,9 +34,9 @@
 function registerOneShot(tag) {
   navigator.serviceWorker.ready
     .then(function(swRegistration) {
-      return swRegistration.sync.register({'tag': tag});
+      return swRegistration.sync.register(tag);
     })
-    .then(function(syncRegistration) {
+    .then(function() {
       sendResultToTest('ok - ' + tag + ' registered');
     })
     .catch(sendErrorToTest);
@@ -52,56 +51,18 @@
     .catch(sendErrorToTest);
 }
 
-function unregisterOneShot(tag) {
-  navigator.serviceWorker.ready
-    .then(function(swRegistration) {
-      return swRegistration.sync.getRegistration(tag);
-    })
-    .then(function(syncRegistration) {
-      if (!syncRegistration) {
-        sendResultToTest('error - ' + tag + ' not found');
-        return;
-      }
-      return syncRegistration.unregister();
-    })
-    .then(function() {
-      sendResultToTest('ok - ' + tag + ' unregistered');
-    })
-    .catch(sendErrorToTest);
-}
-
-function unregisterOneShotTwice(tag) {
-  navigator.serviceWorker.ready
-    .then(function(swRegistration) {
-      return swRegistration.sync.getRegistration(tag);
-    })
-    .then(function(syncRegistration) {
-      if (!syncRegistration) {
-        sendResultToTest('error - ' + tag + ' not found');
-        return;
-      }
-      return syncRegistration.unregister();
-    })
-    .then(function() {
-      return syncRegistration.unregister();
-    })
-    .then(sendErrorToTest, function() {
-      sendResultToTest('ok - ' + tag + ' failed to unregister twice');
-    })
-    .catch(sendErrorToTest);
-}
-
 function getRegistrationOneShot(tag) {
   navigator.serviceWorker.ready
     .then(function(swRegistration) {
-      return swRegistration.sync.getRegistration(tag);
+      return swRegistration.sync.getTags();
     })
-    .then(function(syncRegistration) {
-      if (!syncRegistration) {
+    .then(function(tags) {
+      if (tags.indexOf(tag) >= 0) {
+        sendResultToTest('ok - ' + tag + ' found');
+      } else {
         sendResultToTest('error - ' + tag + ' not found');
         return;
       }
-      sendResultToTest('ok - ' + tag + ' found');
     })
     .catch(sendErrorToTest);
 }
@@ -119,12 +80,9 @@
 function getRegistrationsOneShot(tag) {
   navigator.serviceWorker.ready
     .then(function(swRegistration) {
-      return swRegistration.sync.getRegistrations();
+      return swRegistration.sync.getTags();
     })
-    .then(function(syncRegistrations) {
-      var tags = syncRegistrations.map(function(syncRegistration) {
-        return syncRegistration.tag;
-      });
+    .then(function(tags) {
       sendResultToTest('ok - ' + tags.toString());
     })
     .catch(sendErrorToTest);
@@ -157,44 +115,6 @@
     .catch(sendErrorToTest);
 }
 
-function notifyWhenFinishedOneShot(tag) {
-  navigator.serviceWorker.ready
-    .then(function(swRegistration) {
-      swRegistration.active.postMessage(
-          {action: 'notifyWhenFinished', tag: tag});
-    })
-    .catch(sendErrorToTest);
-}
-
-function notifyWhenFinishedImmediateOneShot(tag) {
-  if (registrationReference == null) {
-    sendResultToTest('error - must call storeRegistration first');
-    return;
-  }
-
-  registrationReference.finished
-    .then(function(success) {
-      sendResultToTest('ok - ' + registrationReference.tag +
-                       ' result: true')
-    }, function(err) {
-      sendResultToTest('ok - ' + registrationReference.tag +
-                       ' result: false')
-    })
-    .catch(sendErrorToTest)
-}
-
-
-function storeRegistration(tag) {
-  navigator.serviceWorker.ready
-    .then(function(swRegistration) {
-      return swRegistration.sync.getRegistration(tag);
-    })
-    .then(function(syncRegistration) {
-      registrationReference = syncRegistration;
-      sendResultToTest('ok - ' + tag + ' stored');
-    })
-    .catch(sendErrorToTest);
-}
 
 // Queue storing asynchronous results received from the Service Worker. Results
 // are sent to the test when requested.
diff --git a/content/test/data/background_sync/service_worker.js b/content/test/data/background_sync/service_worker.js
index 6fedae8..e04bf30d 100644
--- a/content/test/data/background_sync/service_worker.js
+++ b/content/test/data/background_sync/service_worker.js
@@ -9,7 +9,6 @@
 // "delay" - Delays finishing the sync event with event.waitUntil.
 //           Send a postMessage of "completeDelayedOneShot" to finish the
 //           event.
-// "unregister" - Unregisters the sync registration from within the sync event.
 
 'use strict';
 
@@ -38,25 +37,10 @@
     sendMessageToClients('sync', 'ok - delay rejected');
   }
 
-  if (event.data['action'] === 'notifyWhenFinished') {
-    var tag = event.data['tag'];
-    registration.sync.getRegistration(tag)
-      .then(function (syncRegistration) {
-        sendMessageToClients('sync', 'ok - ' + tag + ' finished');
-        return syncRegistration.finished;
-      })
-      .then(function() {
-        sendMessageToClients('sync', tag + " finished result: true");
-      }, function(error) {
-        sendMessageToClients('sync', tag + " finished result: false");
-      })
-      .catch(sendSyncErrorToClients);
-  }
-
   if (event.data['action'] === 'registerOneShot') {
     var tag = event.data['tag'];
-    registration.sync.register({'tag': tag})
-      .then(function (syncRegistration) {
+    registration.sync.register(tag)
+      .then(function () {
         sendMessageToClients('register', 'ok - ' + tag + ' registered in SW');
       })
       .catch(sendSyncErrorToClients);
@@ -64,23 +48,21 @@
 
   if (event.data['action'] === 'getRegistrationOneShot') {
     var tag = event.data['tag'];
-    registration.sync.getRegistration(tag)
-      .then(function(syncRegistration) {
-        if (!syncRegistration) {
+    registration.sync.getTags(tag)
+      .then(function(tags) {
+        if (tags.indexOf(tag) >= 0) {
+          sendMessageToClients('register', 'ok - ' + tag + ' found');
+        } else {
           sendMessageToClients('register', 'error - ' + tag + ' not found');
           return;
         }
-        sendMessageToClients('register', 'ok - ' + tag + ' found');
       })
       .catch(sendSyncErrorToClients);
   }
 
   if (event.data['action'] === 'getRegistrationsOneShot') {
-    registration.sync.getRegistrations()
-      .then(function(syncRegistrations) {
-        var tags = syncRegistrations.map(function(syncRegistration) {
-          return syncRegistration.tag;
-        });
+    registration.sync.getTags()
+      .then(function(tags) {
         sendMessageToClients('register', 'ok - ' + tags.toString());
       })
       .catch(sendSyncErrorToClients);
@@ -103,17 +85,12 @@
     sendMessageToClients('sync', 'error - wrong wait until type');
   }
 
-  if (event.registration === undefined) {
-    sendMessageToClients('sync', 'error - event missing registration');
-    return;
-  }
-
-  if (event.registration.tag === undefined) {
+  if (event.tag === undefined) {
     sendMessageToClients('sync', 'error - registration missing tag');
     return;
   }
 
-  var tag = event.registration.tag;
+  var tag = event.tag;
 
   if (tag === 'delay') {
     var syncPromise = new Promise(function(resolve, reject) {
@@ -124,14 +101,6 @@
     return;
   }
 
-  if (tag === 'unregister') {
-    event.waitUntil(event.registration.unregister()
-      .then(function() {
-        sendMessageToClients('sync', 'ok - unregister completed');
-      }));
-    return;
-  }
-
   sendMessageToClients('sync', tag + ' fired');
 };
 
diff --git a/device/usb/BUILD.gn b/device/usb/BUILD.gn
index c30ae56..8a9f47f7 100644
--- a/device/usb/BUILD.gn
+++ b/device/usb/BUILD.gn
@@ -4,7 +4,7 @@
 
 import("//build/config/features.gni")
 
-assert(!is_android && !is_ios)
+assert(!is_ios)
 
 source_ids = "//third_party/usb_ids/usb.ids"
 generated_ids = "$target_gen_dir/usb_ids_gen.cc"
@@ -57,6 +57,11 @@
       "//dbus",
     ]
   }
+
+  # TODO(moshayedi): crbug.com/549257. Add USB support for Aura on Android.
+  if (is_android) {
+    deps -= [ "//third_party/libusb" ]
+  }
 }
 
 source_set("mocks") {
diff --git a/extensions/browser/api/serial/serial_api.cc b/extensions/browser/api/serial/serial_api.cc
index de70d1a..9b8a89d 100644
--- a/extensions/browser/api/serial/serial_api.cc
+++ b/extensions/browser/api/serial/serial_api.cc
@@ -85,11 +85,14 @@
 void SerialGetDevicesFunction::Work() {
   DCHECK_CURRENTLY_ON(BrowserThread::FILE);
 
+// TODO(moshayedi): crbug.com/549257. Add USB support for Aura on Android.
+#if !defined(OS_ANDROID)
   scoped_ptr<device::SerialDeviceEnumerator> enumerator =
       device::SerialDeviceEnumerator::Create();
   mojo::Array<device::serial::DeviceInfoPtr> devices = enumerator->GetDevices();
   results_ = serial::GetDevices::Results::Create(
       devices.To<std::vector<linked_ptr<serial::DeviceInfo> > >());
+#endif
 }
 
 SerialConnectFunction::SerialConnectFunction() {
diff --git a/extensions/browser/guest_view/web_view/web_view_guest.cc b/extensions/browser/guest_view/web_view/web_view_guest.cc
index 4dedeee8..1715b356 100644
--- a/extensions/browser/guest_view/web_view/web_view_guest.cc
+++ b/extensions/browser/guest_view/web_view/web_view_guest.cc
@@ -129,6 +129,9 @@
 #endif
     case base::TERMINATION_STATUS_PROCESS_WAS_KILLED:
       return "killed";
+#if defined(OS_ANDROID)
+    case base::TERMINATION_STATUS_OOM_PROTECTED:
+#endif
     case base::TERMINATION_STATUS_PROCESS_CRASHED:
       return "crashed";
     case base::TERMINATION_STATUS_LAUNCH_FAILED:
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 97427fe9..0b957479 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -9398,16 +9398,12 @@
   Texture::ImageState image_state;
   gl::GLImage* image =
       ref->texture()->GetLevelImage(ref->texture()->target(), 0, &image_state);
-  if (!image) {
+  if (!image || image_state != Texture::BOUND) {
     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
                        "glScheduleOverlayPlaneCHROMIUM",
                        "unsupported texture format");
     return error::kNoError;
   }
-  if (image_state != Texture::BOUND) {
-    // No-op case for pass-through overlays (such as on Chromecast).
-    return error::kNoError;
-  }
   gfx::OverlayTransform transform = GetGFXOverlayTransform(c.plane_transform);
   if (transform == gfx::OVERLAY_TRANSFORM_INVALID) {
     LOCAL_SET_GL_ERROR(GL_INVALID_ENUM,
diff --git a/headless/OWNERS b/headless/OWNERS
new file mode 100644
index 0000000..f845aaa
--- /dev/null
+++ b/headless/OWNERS
@@ -0,0 +1,2 @@
+skyostil@chromium.org
+alexclarke@chromium.org
diff --git a/ios/chrome/browser/passwords/ios_chrome_password_store_factory.cc b/ios/chrome/browser/passwords/ios_chrome_password_store_factory.cc
index ecae3055..fe82ae7 100644
--- a/ios/chrome/browser/passwords/ios_chrome_password_store_factory.cc
+++ b/ios/chrome/browser/passwords/ios_chrome_password_store_factory.cc
@@ -14,7 +14,6 @@
 #include "components/password_manager/core/browser/login_database.h"
 #include "components/password_manager/core/browser/password_store_default.h"
 #include "components/password_manager/core/browser/password_store_factory_util.h"
-#include "components/password_manager/core/browser/password_store_service.h"
 #include "components/sync_driver/sync_service.h"
 #include "ios/chrome/browser/browser_state/browser_state_otr_helper.h"
 #include "ios/chrome/browser/sync/glue/sync_start_util.h"
@@ -28,12 +27,14 @@
 IOSChromePasswordStoreFactory::GetForBrowserState(
     ios::ChromeBrowserState* browser_state,
     ServiceAccessType access_type) {
-  password_manager::PasswordStoreService* service =
-      static_cast<password_manager::PasswordStoreService*>(
-          GetInstance()->GetServiceForBrowserState(browser_state, true));
-
-  return password_manager::GetPasswordStoreFromService(
-      service, access_type, browser_state->IsOffTheRecord());
+  // |profile| gets always redirected to a non-Incognito profile below, so
+  // Incognito & IMPLICIT_ACCESS means that incognito browsing session would
+  // result in traces in the normal profile without the user knowing it.
+  if (access_type == ServiceAccessType::IMPLICIT_ACCESS &&
+      browser_state->IsOffTheRecord())
+    return nullptr;
+  return make_scoped_refptr(static_cast<password_manager::PasswordStore*>(
+      GetInstance()->GetServiceForBrowserState(browser_state, true).get()));
 }
 
 // static
@@ -58,7 +59,7 @@
 }
 
 IOSChromePasswordStoreFactory::IOSChromePasswordStoreFactory()
-    : BrowserStateKeyedServiceFactory(
+    : RefcountedBrowserStateKeyedServiceFactory(
           "PasswordStore",
           BrowserStateDependencyManager::GetInstance()) {
   DependsOn(ios::WebDataServiceFactory::GetInstance());
@@ -66,7 +67,8 @@
 
 IOSChromePasswordStoreFactory::~IOSChromePasswordStoreFactory() {}
 
-scoped_ptr<KeyedService> IOSChromePasswordStoreFactory::BuildServiceInstanceFor(
+scoped_refptr<RefcountedKeyedService>
+IOSChromePasswordStoreFactory::BuildServiceInstanceFor(
     web::BrowserState* context) const {
   scoped_ptr<password_manager::LoginDatabase> login_db(
       password_manager::CreateLoginDatabase(context->GetStatePath()));
@@ -79,9 +81,14 @@
   scoped_refptr<password_manager::PasswordStore> store =
       new password_manager::PasswordStoreDefault(
           main_thread_runner, db_thread_runner, login_db.Pass());
-  return password_manager::BuildServiceInstanceFromStore(
-      store, ios::sync_start_util::GetFlareForSyncableService(
-                 context->GetStatePath()));
+  if (!store->Init(ios::sync_start_util::GetFlareForSyncableService(
+          context->GetStatePath()))) {
+    // TODO(crbug.com/479725): Remove the LOG once this error is visible in the
+    // UI.
+    LOG(WARNING) << "Could not initialize password store.";
+    return nullptr;
+  }
+  return store;
 }
 
 web::BrowserState* IOSChromePasswordStoreFactory::GetBrowserStateToUse(
diff --git a/ios/chrome/browser/passwords/ios_chrome_password_store_factory.h b/ios/chrome/browser/passwords/ios_chrome_password_store_factory.h
index 506737c9..7fec1a2 100644
--- a/ios/chrome/browser/passwords/ios_chrome_password_store_factory.h
+++ b/ios/chrome/browser/passwords/ios_chrome_password_store_factory.h
@@ -7,7 +7,7 @@
 
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
-#include "components/keyed_service/ios/browser_state_keyed_service_factory.h"
+#include "components/keyed_service/ios/refcounted_browser_state_keyed_service_factory.h"
 
 enum class ServiceAccessType;
 
@@ -26,7 +26,8 @@
 
 // Singleton that owns all PasswordStores and associates them with
 // ios::ChromeBrowserState.
-class IOSChromePasswordStoreFactory : public BrowserStateKeyedServiceFactory {
+class IOSChromePasswordStoreFactory
+    : public RefcountedBrowserStateKeyedServiceFactory {
  public:
   static scoped_refptr<password_manager::PasswordStore> GetForBrowserState(
       ios::ChromeBrowserState* browser_state,
@@ -46,7 +47,7 @@
   ~IOSChromePasswordStoreFactory() override;
 
   // BrowserStateKeyedServiceFactory:
-  scoped_ptr<KeyedService> BuildServiceInstanceFor(
+  scoped_refptr<RefcountedKeyedService> BuildServiceInstanceFor(
       web::BrowserState* context) const override;
   web::BrowserState* GetBrowserStateToUse(
       web::BrowserState* context) const override;
diff --git a/ios/chrome/browser/ui/uikit_ui_util.mm b/ios/chrome/browser/ui/uikit_ui_util.mm
index 09fc391c..c510950 100644
--- a/ios/chrome/browser/ui/uikit_ui_util.mm
+++ b/ios/chrome/browser/ui/uikit_ui_util.mm
@@ -13,6 +13,7 @@
 #include "base/ios/ios_util.h"
 #include "base/logging.h"
 #include "base/mac/foundation_util.h"
+#include "ios/chrome/browser/experimental_flags.h"
 #include "ios/chrome/browser/ui/ui_util.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/l10n/l10n_util_mac.h"
@@ -152,8 +153,12 @@
 UIImage* CaptureView(UIView* view, CGFloat scale) {
   UIGraphicsBeginImageContextWithOptions(view.bounds.size, YES /* opaque */,
                                          scale);
-  CGContext* context = UIGraphicsGetCurrentContext();
-  [view.layer renderInContext:context];
+  if (experimental_flags::IsWKWebViewEnabled()) {
+    [view drawViewHierarchyInRect:view.bounds afterScreenUpdates:NO];
+  } else {
+    CGContext* context = UIGraphicsGetCurrentContext();
+    [view.layer renderInContext:context];
+  }
   UIImage* image = UIGraphicsGetImageFromCurrentImageContext();
   UIGraphicsEndImageContext();
   return image;
diff --git a/ios/provider/ios_provider_chrome.gyp b/ios/provider/ios_provider_chrome.gyp
index 2924b1b7..2a7cb38 100644
--- a/ios/provider/ios_provider_chrome.gyp
+++ b/ios/provider/ios_provider_chrome.gyp
@@ -7,6 +7,7 @@
    },
   'targets': [
     {
+      # GN version: //ios/public/provider/chrome/browser
       'target_name': 'ios_provider_chrome_browser',
       'type': 'static_library',
       'sources': [
diff --git a/ios/public/provider/chrome/browser/BUILD.gn b/ios/public/provider/chrome/browser/BUILD.gn
new file mode 100644
index 0000000..f1cf17ec
--- /dev/null
+++ b/ios/public/provider/chrome/browser/BUILD.gn
@@ -0,0 +1,35 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+source_set("browser") {
+  sources = [
+    "browser_state/chrome_browser_state.cc",
+    "browser_state/chrome_browser_state.h",
+    "browser_state/chrome_browser_state_manager.h",
+    "chrome_browser_provider.cc",
+    "chrome_browser_provider.h",
+    "geolocation_updater_provider.h",
+    "geolocation_updater_provider.mm",
+    "keyed_service_provider.cc",
+    "keyed_service_provider.h",
+    "signin/chrome_identity.h",
+    "signin/chrome_identity.mm",
+    "signin/chrome_identity_service.h",
+    "signin/chrome_identity_service.mm",
+    "signin/signin_error_provider.h",
+    "signin/signin_error_provider.mm",
+    "string_provider.h",
+    "ui/infobar_view_delegate.h",
+    "ui/infobar_view_protocol.h",
+    "updatable_resource_provider.h",
+    "updatable_resource_provider.mm",
+  ]
+
+  deps = [
+    "//base",
+    "//components/autofill/core/browser",
+    "//ios/public/provider/web",
+    "//ios/web",
+  ]
+}
diff --git a/ios/web/app/BUILD.gn b/ios/web/app/BUILD.gn
new file mode 100644
index 0000000..7599a96
--- /dev/null
+++ b/ios/web/app/BUILD.gn
@@ -0,0 +1,31 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+source_set("app") {
+  visibility = [ "//ios/web/public/app" ]
+
+  sources = [
+    "web_main.mm",
+    "web_main_loop.h",
+    "web_main_loop.mm",
+    "web_main_runner.h",
+    "web_main_runner.mm",
+  ]
+
+  deps = [
+    "//base",
+    "//base:i18n",
+    "//crypto",
+    "//ios/web",
+    "//net",
+    "//ui/base",
+    "//ui/gfx",
+    "//ui/gfx/geometry",
+  ]
+
+  libs = [
+    "Foundation.framework",
+    "UIKit.framework",
+  ]
+}
diff --git a/ios/web/ios_web.gyp b/ios/web/ios_web.gyp
index 7d29a00..16e4018 100644
--- a/ios/web/ios_web.gyp
+++ b/ios/web/ios_web.gyp
@@ -8,6 +8,7 @@
    },
   'targets': [
     {
+      # GN version: //ios/web/public/app
       'target_name': 'ios_web_app',
       'type': 'static_library',
       'include_dirs': [
diff --git a/ios/web/ios_web_shell.gyp b/ios/web/ios_web_shell.gyp
index 73601ec..67f5c8a4 100644
--- a/ios/web/ios_web_shell.gyp
+++ b/ios/web/ios_web_shell.gyp
@@ -8,6 +8,7 @@
    },
   'targets': [
     {
+      # GN version: //ios/web/shell:ios_web_shell
       'target_name': 'ios_web_shell',
       'type': 'executable',
       'mac_bundle': 1,
diff --git a/ios/web/public/app/BUILD.gn b/ios/web/public/app/BUILD.gn
new file mode 100644
index 0000000..b2e21aa
--- /dev/null
+++ b/ios/web/public/app/BUILD.gn
@@ -0,0 +1,19 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+source_set("app") {
+  sources = [
+    "web_main.h",
+    "web_main_delegate.h",
+    "web_main_parts.h",
+  ]
+
+  public_deps = [
+    "//base",
+  ]
+
+  deps = [
+    "//ios/web/app",
+  ]
+}
diff --git a/ios/web/shell/BUILD.gn b/ios/web/shell/BUILD.gn
new file mode 100644
index 0000000..3d9e967
--- /dev/null
+++ b/ios/web/shell/BUILD.gn
@@ -0,0 +1,70 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//build/config/ios/rules.gni")
+
+ios_app("ios_web_shell") {
+  info_plist = "Info.plist"
+  app_name = "ios_web_shell"
+  entitlements_path = ""
+  code_signing_identity = ""
+
+  sources = [
+    "app_delegate.h",
+    "app_delegate.mm",
+    "shell_browser_state.h",
+    "shell_browser_state.mm",
+    "shell_main_delegate.h",
+    "shell_main_delegate.mm",
+    "shell_network_delegate.cc",
+    "shell_network_delegate.h",
+    "shell_url_request_context_getter.cc",
+    "shell_url_request_context_getter.h",
+    "shell_web_client.h",
+    "shell_web_client.mm",
+    "shell_web_main_parts.h",
+    "shell_web_main_parts.mm",
+    "view_controller.h",
+    "view_controller.mm",
+    "web_exe_main.mm",
+  ]
+
+  deps = [
+    "//base",
+    "//ios/web",
+    "//ios/web/public/app",
+    "//net",
+    "//net:extras",
+    "//ui/base",
+
+    # All shared libraries must have the sanitizer deps to properly link in
+    # asan mode (this target will be empty in other cases).
+    "//build/config/sanitizers:deps",
+  ]
+
+  ldflags = [
+    "-Xlinker",
+    "-objc_abi_version",
+    "-Xlinker",
+    "2",
+  ]
+
+  libs = [
+    "CoreGraphics.framework",
+    "CoreFoundation.framework",
+    "Foundation.framework",
+    "UIKit.framework",
+  ]
+
+  # TODO(crbug.com/546283): once gn supports bundle resources, add support for
+  # the following gyp code:
+  #
+  # 'mac_bundle_resources': [
+  #   'shell/Default.png',
+  #   'shell/MainView.xib',
+  #   'shell/textfield_background@2x.png',
+  #   'shell/toolbar_back@2x.png',
+  #   'shell/toolbar_forward@2x.png',
+  # ],
+}
diff --git a/ios/web/web_state/ui/crw_web_controller_unittest.mm b/ios/web/web_state/ui/crw_web_controller_unittest.mm
index 0f3e338..219ed09 100644
--- a/ios/web/web_state/ui/crw_web_controller_unittest.mm
+++ b/ios/web/web_state/ui/crw_web_controller_unittest.mm
@@ -1293,9 +1293,7 @@
   CR_TEST_REQUIRES_WK_WEB_VIEW();
 
   [[[mockWebView_ stub] andReturn:[NSURL URLWithString:kTestURLString]] URL];
-#if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW)
   [[[mockWebView_ stub] andReturnBool:NO] hasOnlySecureContent];
-#endif
 
   // Stub out the injection process.
   [[mockWebView_ stub] evaluateJavaScript:OCMOCK_ANY
diff --git a/ios/web/web_state/ui/crw_wk_web_view_web_controller.mm b/ios/web/web_state/ui/crw_wk_web_view_web_controller.mm
index a3eaff3..a254291 100644
--- a/ios/web/web_state/ui/crw_wk_web_view_web_controller.mm
+++ b/ios/web/web_state/ui/crw_wk_web_view_web_controller.mm
@@ -216,17 +216,11 @@
 // changed.
 @property(nonatomic, readonly) NSDictionary* wkWebViewObservers;
 
-// Returns the string to use as the request group ID in the user agent. Returns
-// nil unless the network stack is enabled.
-@property(nonatomic, readonly) NSString* requestGroupIDForUserAgent;
-
 // Activity indicator group ID for this web controller.
 @property(nonatomic, readonly) NSString* activityIndicatorGroupID;
 
-#if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW)
 // Identifier used for storing and retrieving certificates.
 @property(nonatomic, readonly) int certGroupID;
-#endif  // #if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW)
 
 // Returns the WKWebViewConfigurationProvider associated with the web
 // controller's BrowserState.
@@ -291,10 +285,8 @@
 // Convenience method to inform CWRWebDelegate about a blocked popup.
 - (void)didBlockPopupWithURL:(GURL)popupURL sourceURL:(GURL)sourceURL;
 
-#if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW)
 // Called when a load ends in an SSL error and certificate chain.
 - (void)handleSSLCertError:(NSError*)error;
-#endif
 
 // Adds an activity indicator tasks for this web controller.
 - (void)addActivityIndicatorTask;
@@ -302,8 +294,6 @@
 // Clears all activity indicator tasks for this web controller.
 - (void)clearActivityIndicatorTasks;
 
-#if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW)
-
 // Updates |security_style| and |cert_status| for the NavigationItem with ID
 // |navigationItemID|, if URL and certificate chain still match |host| and
 // |certChain|.
@@ -322,7 +312,6 @@
 // Updates SSL status for the current navigation item based on the information
 // provided by web view.
 - (void)updateSSLStatusForCurrentNavigationItem;
-#endif
 
 // Used in webView:didReceiveAuthenticationChallenge:completionHandler: to reply
 // with NSURLSessionAuthChallengeDisposition and credentials.
@@ -360,14 +349,12 @@
 // NSURLErrorCancelled code should be cancelled.
 - (BOOL)shouldAbortLoadForCancelledError:(NSError*)error;
 
-#if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW)
 // Called when WKWebView estimatedProgress has been changed.
 - (void)webViewEstimatedProgressDidChange;
 
 // Called when WKWebView certificateChain or hasOnlySecureContent property has
 // changed.
 - (void)webViewSecurityFeaturesDidChange;
-#endif  // !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW)
 
 // Called when WKWebView loading state has been changed.
 - (void)webViewLoadingStateDidChange;
@@ -423,12 +410,10 @@
   web::EvaluateJavaScript(_wkWebView, script, nil);
 }
 
-#if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW)
 - (void)terminateNetworkActivity {
   web::CertStore::GetInstance()->RemoveCertsForGroup(self.certGroupID);
   [super terminateNetworkActivity];
 }
-#endif  // #if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW)
 
 - (void)setPageDialogOpenPolicy:(web::PageDialogOpenPolicy)policy {
   // TODO(eugenebut): implement dialogs/windows suppression using
@@ -499,8 +484,7 @@
 // TODO(stuartmorgan): Remove this method and use the API for WKWebView,
 // making the reset-on-each-load behavior specific to the UIWebView subclass.
 - (void)registerUserAgent {
-  web::BuildAndRegisterUserAgentForUIWebView([self requestGroupIDForUserAgent],
-                                             [self useDesktopUserAgent]);
+  web::BuildAndRegisterUserAgentForUIWebView(nil, [self useDesktopUserAgent]);
 }
 
 - (BOOL)isCurrentNavigationItemPOST {
@@ -693,38 +677,26 @@
 
 - (NSDictionary*)wkWebViewObservers {
   return @{
-#if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW)
-    @"estimatedProgress" : @"webViewEstimatedProgressDidChange",
     @"certificateChain" : @"webViewSecurityFeaturesDidChange",
+    @"estimatedProgress" : @"webViewEstimatedProgressDidChange",
     @"hasOnlySecureContent" : @"webViewSecurityFeaturesDidChange",
-#endif
     @"loading" : @"webViewLoadingStateDidChange",
     @"title" : @"webViewTitleDidChange",
     @"URL" : @"webViewURLDidChange",
   };
 }
 
-- (NSString*)requestGroupIDForUserAgent {
-#if defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW)
-  return self.webStateImpl->GetRequestGroupID();
-#else
-  return nil;
-#endif
-}
-
 - (NSString*)activityIndicatorGroupID {
   return [NSString stringWithFormat:
       @"WKWebViewWebController.NetworkActivityIndicatorKey.%@",
           self.webStateImpl->GetRequestGroupID()];
 }
 
-#if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW)
 - (int)certGroupID {
   DCHECK(self.webStateImpl);
   // Request tracker IDs are used as certificate groups.
   return self.webStateImpl->GetRequestTracker()->identifier();
 }
-#endif
 
 - (web::WKWebViewConfigurationProvider&)webViewConfigurationProvider {
   DCHECK(self.webStateImpl);
@@ -745,7 +717,6 @@
 - (WKWebView*)createWebViewWithConfiguration:(WKWebViewConfiguration*)config {
   return [web::CreateWKWebView(CGRectZero, config,
                                self.webStateImpl->GetBrowserState(),
-                               [self requestGroupIDForUserAgent],
                                [self useDesktopUserAgent]) autorelease];
 }
 
@@ -947,7 +918,6 @@
   });
 }
 
-#if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW)
 - (void)handleSSLCertError:(NSError*)error {
   DCHECK(web::IsWKWebViewSSLCertError(error));
 
@@ -1003,7 +973,6 @@
                         }];
   [self loadCancelled];
 }
-#endif  // #if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW)
 
 - (void)addActivityIndicatorTask {
   [[CRWNetworkActivityIndicatorManager sharedInstance]
@@ -1015,8 +984,6 @@
       clearNetworkTasksForGroup:[self activityIndicatorGroupID]];
 }
 
-#if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW)
-
 - (void)updateSSLStatusForNavigationItemWithID:(int)navigationItemID
                                      certChain:(NSArray*)chain
                                           host:(NSString*)host
@@ -1142,8 +1109,6 @@
   }
 }
 
-#endif  // !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW)
-
 - (void)processAuthChallenge:(NSURLAuthenticationChallenge*)challenge
          forCertAcceptPolicy:(web::CertAcceptPolicy)policy
                   certStatus:(net::CertStatus)certStatus
@@ -1436,8 +1401,6 @@
     [self performSelector:NSSelectorFromString(dispatcherSelectorName)];
 }
 
-#if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW)
-// TODO(eugenebut): use WKWebView progress even if Chrome net stack is enabled.
 - (void)webViewEstimatedProgressDidChange {
   if ([self.delegate respondsToSelector:
           @selector(webController:didUpdateProgress:)]) {
@@ -1455,8 +1418,6 @@
   [self updateSSLStatusForCurrentNavigationItem];
 }
 
-#endif  // !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW)
-
 - (void)webViewLoadingStateDidChange {
   if ([_wkWebView isLoading]) {
     [self addActivityIndicatorTask];
@@ -1655,24 +1616,9 @@
   if (![_pendingNavigationInfo cancelled]) {
     error = WKWebViewErrorWithSource(error, PROVISIONAL_LOAD);
 
-#if defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW)
-    // For WKWebViews, the underlying errors for errors reported by the net
-    // stack are not copied over when transferring the errors from the IO
-    // thread.  For cancelled errors that trigger load abortions, translate the
-    // error early to trigger |-discardNonCommittedEntries| from
-    // |-handleLoadError:inMainFrame:|.
-    if (error.code == NSURLErrorCancelled &&
-        [self shouldAbortLoadForCancelledError:error] &&
-        !error.userInfo[NSUnderlyingErrorKey]) {
-      error = web::NetErrorFromError(error);
-    }
-#endif  // defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW)
-
-#if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW)
     if (web::IsWKWebViewSSLCertError(error))
       [self handleSSLCertError:error];
     else
-#endif
       [self handleLoadError:error inMainFrame:YES];
   }
 
@@ -1699,9 +1645,7 @@
   [self commitPendingNavigationInfo];
   [self webPageChanged];
 
-#if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW)
   [self updateSSLStatusForCurrentNavigationItem];
-#endif
 
   // Report cases where SSL cert is missing for a secure connection.
   if (_documentURL.SchemeIsCryptographic()) {
diff --git a/ios/web/web_state/web_view_internal_creation_util.h b/ios/web/web_state/web_view_internal_creation_util.h
index c53fae80..ee2296b 100644
--- a/ios/web/web_state/web_view_internal_creation_util.h
+++ b/ios/web/web_state/web_view_internal_creation_util.h
@@ -31,8 +31,8 @@
 // TODO(shreyasv): Rename to CreateUIWebView.
 UIWebView* CreateWebView(CGRect frame);
 
-// Creates and returns a WKWebView. The returned WKWebView will have a
-// user agent string that includes the |request_group_id|.
+// Creates a new WKWebView for displaying regular web content and registers a
+// user agent for it.
 //
 // Preconditions for creation of a WKWebView:
 // 1) |browser_state|, |configuration| are not null.
@@ -44,7 +44,6 @@
 WKWebView* CreateWKWebView(CGRect frame,
                            WKWebViewConfiguration* configuration,
                            BrowserState* browser_state,
-                           NSString* request_group_id,
                            BOOL use_desktop_user_agent);
 
 // Creates and returns a new WKWebView for displaying regular web content.
diff --git a/ios/web/web_state/web_view_internal_creation_util.mm b/ios/web/web_state/web_view_internal_creation_util.mm
index 3fdb1b15..a9a69ce 100644
--- a/ios/web/web_state/web_view_internal_creation_util.mm
+++ b/ios/web/web_state/web_view_internal_creation_util.mm
@@ -163,10 +163,8 @@
 WKWebView* CreateWKWebView(CGRect frame,
                            WKWebViewConfiguration* configuration,
                            BrowserState* browser_state,
-                           NSString* request_group_id,
                            BOOL use_desktop_user_agent) {
-  web::BuildAndRegisterUserAgentForUIWebView(request_group_id,
-                                             use_desktop_user_agent);
+  web::BuildAndRegisterUserAgentForUIWebView(nil, use_desktop_user_agent);
   return CreateWKWebView(frame, configuration, browser_state);
 }
 
diff --git a/ipc/brokerable_attachment.h b/ipc/brokerable_attachment.h
index ce3082c..6761f22 100644
--- a/ipc/brokerable_attachment.h
+++ b/ipc/brokerable_attachment.h
@@ -7,6 +7,8 @@
 
 #include <stdint.h>
 
+#include <algorithm>
+
 #include "base/macros.h"
 #include "ipc/ipc_export.h"
 #include "ipc/ipc_message_attachment.h"
@@ -37,21 +39,12 @@
     void SerializeToBuffer(char* start_address, size_t size);
 
     bool operator==(const AttachmentId& rhs) const {
-      for (size_t i = 0; i < kNonceSize; ++i) {
-        if (nonce[i] != rhs.nonce[i])
-          return false;
-      }
-      return true;
+      return std::equal(nonce, nonce + kNonceSize, rhs.nonce);
     }
 
     bool operator<(const AttachmentId& rhs) const {
-      for (size_t i = 0; i < kNonceSize; ++i) {
-        if (nonce[i] < rhs.nonce[i])
-          return true;
-        if (nonce[i] > rhs.nonce[i])
-          return false;
-      }
-      return false;
+      return std::lexicographical_compare(nonce, nonce + kNonceSize, rhs.nonce,
+                                          rhs.nonce + kNonceSize);
     }
   };
 
diff --git a/media/base/video_frame.cc b/media/base/video_frame.cc
index 3be20da..286ed438 100644
--- a/media/base/video_frame.cc
+++ b/media/base/video_frame.cc
@@ -226,8 +226,8 @@
     const gfx::Rect& visible_rect,
     const gfx::Size& natural_size,
     base::TimeDelta timestamp) {
-  if (format != PIXEL_FORMAT_ARGB && format != PIXEL_FORMAT_XRGB &&
-      format != PIXEL_FORMAT_UYVY && format != PIXEL_FORMAT_NV12) {
+  if (format != PIXEL_FORMAT_ARGB && format != PIXEL_FORMAT_UYVY &&
+      format != PIXEL_FORMAT_NV12) {
     DLOG(ERROR) << "Unsupported pixel format supported, got "
                 << VideoPixelFormatToString(format);
     return nullptr;
diff --git a/media/test/data/test-25fps.h264.md5 b/media/test/data/test-25fps.h264.md5
index 1f6a6fa..ecf64a0 100644
--- a/media/test/data/test-25fps.h264.md5
+++ b/media/test/data/test-25fps.h264.md5
@@ -1,8 +1,6 @@
 # --test_video_data="test-25fps.h264:320:240:250:258:35:150:1"
-# Intel Haswell - EGL
-92a0c14b4c1a13ca21317d2e75f17f76
-# Intel Ivy Bridge - EGL
-75d2f70272df8687dbda32e2eddd0a00
+# Intel Ivy Bridge / Haswell / Broadwell - EGL
+27ddce017b884f8bbfa159ad180a71d2
 # Intel Sandy Brige - EGL
 42e78b8ac231dc24e6db5fac2d26da7b
 # Intel - Haswell - X11
@@ -14,5 +12,12 @@
 04436cf1cf06b4bb6c1efd838e68257d
 # ARM - Tegra
 b55cda7d10c37104d8c49d27c2699e40
+
+# TODO(llandwerlin): Remove the following hashes when the libva-intel-driver
+# is updated.
+# Intel Haswell - EGL
+92a0c14b4c1a13ca21317d2e75f17f76
+# Intel Ivy Bridge - EGL
+75d2f70272df8687dbda32e2eddd0a00
 # Intel (various) libva-intel-driver 1.5.1 with VA_PROC_PIPELINE_FAST
 8bbc743c7ac92c2442d09e8b3fb9f4f5
diff --git a/media/test/data/test-25fps.vp8.md5 b/media/test/data/test-25fps.vp8.md5
index 6ae8188..4692109 100644
--- a/media/test/data/test-25fps.vp8.md5
+++ b/media/test/data/test-25fps.vp8.md5
@@ -3,4 +3,9 @@
 # ARM - Tegra
 cd355b553ce7660283c52675232e9227
 # Intel - BDW
+32a3c4257dac03df92a5c7593ee7e31f
+
+# TODO(llandwerlin): Remove the following hash when the libva-intel-driver
+# is updated.
+# Intel - BDW
 4da7ec5484a99195c2c05b5e591940f9
diff --git a/net/cookies/canonical_cookie.cc b/net/cookies/canonical_cookie.cc
index f57f642..ddf35e05 100644
--- a/net/cookies/canonical_cookie.cc
+++ b/net/cookies/canonical_cookie.cc
@@ -116,6 +116,21 @@
   return a.Path().compare(b.Path());
 }
 
+// Returns true if the cookie does not violate any constraints imposed
+// by the cookie name's prefix, as described in
+// https://tools.ietf.org/html/draft-west-cookie-prefixes
+bool IsCookiePrefixValid(const GURL& url, const ParsedCookie& parsed_cookie) {
+  const char kSecurePrefix[] = "$Secure-";
+  const char kHostPrefix[] = "$Host-";
+  if (parsed_cookie.Name().find(kSecurePrefix) == 0)
+    return parsed_cookie.IsSecure() && url.SchemeIsCryptographic();
+  if (parsed_cookie.Name().find(kHostPrefix) == 0) {
+    return parsed_cookie.IsSecure() && url.SchemeIsCryptographic() &&
+           !parsed_cookie.HasDomain() && parsed_cookie.Path() == "/";
+  }
+  return true;
+}
+
 }  // namespace
 
 CanonicalCookie::CanonicalCookie()
@@ -248,6 +263,12 @@
                                                          creation_time,
                                                          server_time);
 
+  if (options.enforce_prefixes() && !IsCookiePrefixValid(url, parsed_cookie)) {
+    VLOG(kVlogSetCookies)
+        << "Create() failed because the cookie violated prefix rules.";
+    return nullptr;
+  }
+
   return new CanonicalCookie(
       url, parsed_cookie.Name(), parsed_cookie.Value(), cookie_domain,
       cookie_path, creation_time, cookie_expires, creation_time,
diff --git a/net/cookies/canonical_cookie_unittest.cc b/net/cookies/canonical_cookie_unittest.cc
index 58c12ca6..cc0426e 100644
--- a/net/cookies/canonical_cookie_unittest.cc
+++ b/net/cookies/canonical_cookie_unittest.cc
@@ -449,4 +449,93 @@
   check_consistency(*cookie_different_path, *cookie_different_value);
 }
 
+TEST(CanonicalCookieTest, SecureCookiePrefix) {
+  GURL https_url("https://www.example.test");
+  GURL http_url("http://www.example.test");
+  base::Time creation_time = base::Time::Now();
+  CookieOptions options;
+  options.set_enforce_prefixes();
+
+  // A $Secure- cookie must be Secure.
+  EXPECT_EQ(nullptr, make_scoped_ptr(CanonicalCookie::Create(
+                         https_url, "$Secure-A=B", creation_time, options)));
+  EXPECT_EQ(nullptr,
+            make_scoped_ptr(CanonicalCookie::Create(
+                https_url, "$Secure-A=B; httponly", creation_time, options)));
+
+  // A typoed prefix does not have to be Secure.
+  EXPECT_NE(nullptr,
+            make_scoped_ptr(CanonicalCookie::Create(
+                https_url, "$secure-A=B; Secure", creation_time, options)));
+  EXPECT_NE(nullptr, make_scoped_ptr(CanonicalCookie::Create(
+                         https_url, "$secure-A=C;", creation_time, options)));
+  EXPECT_NE(nullptr,
+            make_scoped_ptr(CanonicalCookie::Create(
+                https_url, "$SecureA=B; Secure", creation_time, options)));
+  EXPECT_NE(nullptr, make_scoped_ptr(CanonicalCookie::Create(
+                         https_url, "$SecureA=C;", creation_time, options)));
+
+  // A $Secure- cookie can't be set on a non-secure origin.
+  EXPECT_EQ(nullptr,
+            make_scoped_ptr(CanonicalCookie::Create(
+                http_url, "$Secure-A=B; Secure", creation_time, options)));
+}
+
+TEST(CanonicalCookieTest, HostCookiePrefix) {
+  GURL https_url("https://www.example.test");
+  GURL http_url("http://www.example.test");
+  base::Time creation_time = base::Time::Now();
+  CookieOptions options;
+  options.set_enforce_prefixes();
+  std::string domain = https_url.host();
+
+  // A $Host- cookie must be Secure.
+  EXPECT_EQ(nullptr, make_scoped_ptr(CanonicalCookie::Create(
+                         https_url, "$Host-A=B;", creation_time, options)));
+  EXPECT_EQ(nullptr, make_scoped_ptr(CanonicalCookie::Create(
+                         https_url, "$Host-A=B; Domain=" + domain + "; Path=/;",
+                         creation_time, options)));
+  EXPECT_NE(nullptr, make_scoped_ptr(CanonicalCookie::Create(
+                         https_url, "$Host-A=B; Path=/; Secure;", creation_time,
+                         options)));
+
+  // A $Host- cookie must be set from a secure scheme.
+  EXPECT_EQ(nullptr,
+            make_scoped_ptr(CanonicalCookie::Create(
+                http_url, "$Host-A=B; Domain=" + domain + "; Path=/; Secure;",
+                creation_time, options)));
+  EXPECT_NE(nullptr, make_scoped_ptr(CanonicalCookie::Create(
+                         https_url, "$Host-A=B; Path=/; Secure;", creation_time,
+                         options)));
+
+  // A $Host- cookie can't have a Domain.
+  EXPECT_EQ(nullptr,
+            make_scoped_ptr(CanonicalCookie::Create(
+                https_url, "$Host-A=B; Domain=" + domain + "; Path=/; Secure;",
+                creation_time, options)));
+  EXPECT_EQ(nullptr, make_scoped_ptr(CanonicalCookie::Create(
+                         https_url, "$Host-A=B; Domain=" + domain + "; Secure;",
+                         creation_time, options)));
+
+  // A $Host- cookie must have a Path of "/".
+  EXPECT_EQ(nullptr, make_scoped_ptr(CanonicalCookie::Create(
+                         https_url, "$Host-A=B; Path=/foo; Secure;",
+                         creation_time, options)));
+  EXPECT_EQ(nullptr,
+            make_scoped_ptr(CanonicalCookie::Create(
+                https_url, "$Host-A=B; Secure;", creation_time, options)));
+  EXPECT_NE(nullptr, make_scoped_ptr(CanonicalCookie::Create(
+                         https_url, "$Host-A=B; Secure; Path=/;", creation_time,
+                         options)));
+
+  // Rules don't apply for a typoed prefix.
+  EXPECT_NE(nullptr,
+            make_scoped_ptr(CanonicalCookie::Create(
+                http_url, "$host-A=B; Domain=" + domain + "; Path=/; Secure;",
+                creation_time, options)));
+  EXPECT_NE(nullptr, make_scoped_ptr(CanonicalCookie::Create(
+                         https_url, "$HostA=B; Domain=" + domain + "; Secure;",
+                         creation_time, options)));
+}
+
 }  // namespace net
diff --git a/net/cookies/cookie_monster.cc b/net/cookies/cookie_monster.cc
index 9adfa1b..6304eb6c 100644
--- a/net/cookies/cookie_monster.cc
+++ b/net/cookies/cookie_monster.cc
@@ -332,13 +332,6 @@
   proxy->PostTask(FROM_HERE, base::Bind(callback, cookie, removed));
 }
 
-bool CheckCookiePrefix(CanonicalCookie* cc, const CookieOptions& options) {
-  const char kSecurePrefix[] = "$Secure-";
-  if (cc->Name().find(kSecurePrefix) == 0)
-    return cc->IsSecure() && cc->Source().SchemeIsCryptographic();
-  return true;
-}
-
 }  // namespace
 
 CookieMonster::CookieMonster(PersistentCookieStore* store,
@@ -1895,12 +1888,6 @@
   const std::string key(GetKey((*cc)->Domain()));
   bool already_expired = (*cc)->IsExpired(creation_time);
 
-  if (options.enforce_prefixes() && !CheckCookiePrefix(cc->get(), options)) {
-    VLOG(kVlogSetCookies) << "SetCookie() not storing cookie '" << (*cc)->Name()
-                          << "' that violates prefix rules.";
-    return false;
-  }
-
   if (DeleteAnyEquivalentCookie(key, **cc, options.exclude_httponly(),
                                 already_expired)) {
     VLOG(kVlogSetCookies) << "SetCookie() not clobbering httponly cookie";
diff --git a/net/cookies/cookie_monster_unittest.cc b/net/cookies/cookie_monster_unittest.cc
index 82ae3a2..fddd625 100644
--- a/net/cookies/cookie_monster_unittest.cc
+++ b/net/cookies/cookie_monster_unittest.cc
@@ -2967,29 +2967,6 @@
       CookieMonster::COOKIE_SOURCE_NONSECURE_COOKIE_NONCRYPTOGRAPHIC_SCHEME, 1);
 }
 
-TEST_F(CookieMonsterTest, SecureCookiePrefix) {
-  scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
-  // A $Secure- cookie must be Secure.
-  EXPECT_FALSE(SetCookie(cm.get(), https_www_google_.url(), "$Secure-A=B"));
-  EXPECT_FALSE(
-      SetCookie(cm.get(), https_www_google_.url(), "$Secure-A=B; httponly"));
-
-  // A typoed prefix does not have to be Secure.
-  EXPECT_TRUE(
-      SetCookie(cm.get(), https_www_google_.url(), "$secure-A=B; Secure"));
-  EXPECT_TRUE(SetCookie(cm.get(), https_www_google_.url(), "$secure-A=C;"));
-  EXPECT_TRUE(
-      SetCookie(cm.get(), https_www_google_.url(), "$SecureA=B; Secure"));
-  EXPECT_TRUE(SetCookie(cm.get(), https_www_google_.url(), "$SecureA=C;"));
-
-  EXPECT_TRUE(
-      SetCookie(cm.get(), https_www_google_.url(), "$Secure-A=B; Secure"));
-
-  // A $Secure- cookie can't be set on a non-secure origin.
-  EXPECT_FALSE(
-      SetCookie(cm.get(), http_www_google_.url(), "$Secure-A=B; Secure"));
-}
-
 class CookieMonsterNotificationTest : public CookieMonsterTest {
  public:
   CookieMonsterNotificationTest()
diff --git a/remoting/android/java/src/org/chromium/chromoting/DesktopCanvas.java b/remoting/android/java/src/org/chromium/chromoting/DesktopCanvas.java
new file mode 100644
index 0000000..b9edf31
--- /dev/null
+++ b/remoting/android/java/src/org/chromium/chromoting/DesktopCanvas.java
@@ -0,0 +1,196 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chromoting;
+
+import android.graphics.PointF;
+import android.graphics.RectF;
+
+/**
+ * This class is responsible for transforming the desktop image matrix.
+ */
+public class DesktopCanvas {
+    /**
+     * Maximum allowed zoom level - see {@link #repositionImageWithZoom()}.
+     */
+    private static final float MAX_ZOOM_FACTOR = 100.0f;
+
+    private final DesktopViewInterface mViewer;
+    private final RenderData mRenderData;
+
+    /**
+     * The current cursor position is stored here as a float so that the desktop image can be
+     * positioned with sub-pixel accuracy to give a smoother panning animation at high zoom levels.
+     */
+    private PointF mCursorPosition = new PointF();
+
+    /**
+     * Represents the amount of vertical space in pixels used by the soft input device and
+     * accompanying system UI.
+     */
+    private int mInputMethodOffsetY = 0;
+
+    /**
+     * Represents the amount of horizontal space in pixels used by the soft input device and
+     * accompanying system UI.
+     */
+    private int mInputMethodOffsetX = 0;
+
+    /** Used to determine whether the view should be locked to the cursor. */
+    private boolean mCenterCursorInView = true;
+
+    public DesktopCanvas(DesktopViewInterface viewer, RenderData renderData) {
+        mViewer = viewer;
+        mRenderData = renderData;
+    }
+
+    public void setCenterCursorInView(boolean centerCursor) {
+        mCenterCursorInView = centerCursor;
+    }
+
+    public PointF getCursorPosition() {
+        return new PointF(mCursorPosition.x, mCursorPosition.y);
+    }
+
+    public void setCursorPosition(float newX, float newY) {
+        mCursorPosition.set(newX, newY);
+    }
+
+    public void setInputMethodOffsetValues(int offsetX, int offsetY) {
+        mInputMethodOffsetX = offsetX;
+        mInputMethodOffsetY = offsetY;
+    }
+
+    /** Repositions the image by zooming it such that the complete image fits on the screen. */
+    public void resizeImageToFitScreen() {
+        synchronized (mRenderData) {
+            // Protect against being called before the image has been initialized.
+            if (mRenderData.imageWidth == 0 || mRenderData.imageHeight == 0) {
+                return;
+            }
+
+            float screenToImageScale = 1.0f;
+            float[] imageSize = {mRenderData.imageWidth, mRenderData.imageHeight};
+            mRenderData.transform.mapVectors(imageSize);
+
+            // If the image is smaller than the screen in both dimensions, then we want
+            // to scale it up to fit.
+            boolean scaleImageUp = imageSize[0] < mRenderData.screenWidth
+                    && imageSize[1] < mRenderData.screenHeight;
+
+            // If the image is larger than the screen in any dimension, we want to
+            // shrink it to fit.
+            boolean scaleImageDown = imageSize[0] > mRenderData.screenWidth
+                    || imageSize[1] > mRenderData.screenHeight;
+
+            if (scaleImageUp || scaleImageDown) {
+                // Displayed image is too small or too large to fit the screen dimensions.
+                // Apply the minimum scale needed to fit both the width and height.
+                screenToImageScale =
+                        Math.min((float) mRenderData.screenWidth / mRenderData.imageWidth,
+                                 (float) mRenderData.screenHeight / mRenderData.imageHeight);
+                mRenderData.transform.setScale(screenToImageScale, screenToImageScale);
+            }
+        }
+
+        repositionImage();
+    }
+
+    /**
+     * Repositions the image by translating it (without affecting the zoom level) to place the
+     * cursor close to the center of the screen.
+     */
+    public void repositionImage() {
+        synchronized (mRenderData) {
+            float adjustedScreenWidth = mRenderData.screenWidth - mInputMethodOffsetX;
+            float adjustedScreenHeight = mRenderData.screenHeight - mInputMethodOffsetY;
+
+            if (mCenterCursorInView) {
+                // For indirect input modes such as Trackpad emulation, we want to try to position
+                // the view so the cursor is centered.  We move it here and then make adjustments
+                // below as needed to keep as much of the image on screen as possible.
+
+                // Get the current cursor position in screen coordinates.
+                float[] cursorScreen = {mCursorPosition.x, mCursorPosition.y};
+                mRenderData.transform.mapPoints(cursorScreen);
+
+                // Translate so the cursor is displayed in the middle of the screen.
+                mRenderData.transform.postTranslate(
+                        (float) adjustedScreenWidth / 2 - cursorScreen[0],
+                        (float) adjustedScreenHeight / 2 - cursorScreen[1]);
+            }
+
+            // Get the coordinates of the desktop rectangle (top-left/bottom-right corners) in
+            // screen coordinates. Order is: left, top, right, bottom.
+            RectF rectScreen = new RectF(0, 0, mRenderData.imageWidth, mRenderData.imageHeight);
+            mRenderData.transform.mapRect(rectScreen);
+
+            float leftDelta = rectScreen.left;
+            float rightDelta = rectScreen.right - mRenderData.screenWidth + mInputMethodOffsetX;
+            float topDelta = rectScreen.top;
+            float bottomDelta = rectScreen.bottom - mRenderData.screenHeight + mInputMethodOffsetY;
+            float xAdjust = 0;
+            float yAdjust = 0;
+
+            if (rectScreen.right - rectScreen.left < adjustedScreenWidth) {
+                // Image is narrower than the screen, so center it.
+                xAdjust = -(rightDelta + leftDelta) / 2;
+            } else if (leftDelta > 0 && rightDelta > 0) {
+                // Panning the image left will show more of it.
+                xAdjust = -Math.min(leftDelta, rightDelta);
+            } else if (leftDelta < 0 && rightDelta < 0) {
+                // Pan the image right.
+                xAdjust = Math.min(-leftDelta, -rightDelta);
+            }
+
+            // Apply similar logic for yAdjust.
+            if (rectScreen.bottom - rectScreen.top < adjustedScreenHeight) {
+                yAdjust = -(bottomDelta + topDelta) / 2;
+            } else if (topDelta > 0 && bottomDelta > 0) {
+                yAdjust = -Math.min(topDelta, bottomDelta);
+            } else if (topDelta < 0 && bottomDelta < 0) {
+                yAdjust = Math.min(-topDelta, -bottomDelta);
+            }
+
+            mRenderData.transform.postTranslate(xAdjust, yAdjust);
+
+            mViewer.transformationChanged();
+        }
+    }
+
+    /**
+     * Repositions the image by translating and zooming it, to keep the zoom level within sensible
+     * limits. The minimum zoom level is chosen to avoid black space around all 4 sides. The
+     * maximum zoom level is set arbitrarily, so that the user can zoom out again in a reasonable
+     * time, and to prevent arithmetic overflow problems from displaying the image.
+     */
+    public void repositionImageWithZoom() {
+        synchronized (mRenderData) {
+            // Avoid division by zero in case this gets called before the image size is initialized.
+            if (mRenderData.imageWidth == 0 || mRenderData.imageHeight == 0) {
+                return;
+            }
+
+            // Zoom out if the zoom level is too high.
+            float currentZoomLevel = mRenderData.transform.mapRadius(1.0f);
+            if (currentZoomLevel > MAX_ZOOM_FACTOR) {
+                mRenderData.transform.setScale(MAX_ZOOM_FACTOR, MAX_ZOOM_FACTOR);
+            }
+
+            // Get image size scaled to screen coordinates.
+            float[] imageSize = {mRenderData.imageWidth, mRenderData.imageHeight};
+            mRenderData.transform.mapVectors(imageSize);
+
+            if (imageSize[0] < mRenderData.screenWidth && imageSize[1] < mRenderData.screenHeight) {
+                // Displayed image is too small in both directions, so apply the minimum zoom
+                // level needed to fit either the width or height.
+                float scale = Math.min((float) mRenderData.screenWidth / mRenderData.imageWidth,
+                                       (float) mRenderData.screenHeight / mRenderData.imageHeight);
+                mRenderData.transform.setScale(scale, scale);
+            }
+        }
+
+        repositionImage();
+    }
+}
diff --git a/remoting/android/java/src/org/chromium/chromoting/DesktopView.java b/remoting/android/java/src/org/chromium/chromoting/DesktopView.java
index d517f4a2..466012b9 100644
--- a/remoting/android/java/src/org/chromium/chromoting/DesktopView.java
+++ b/remoting/android/java/src/org/chromium/chromoting/DesktopView.java
@@ -35,10 +35,13 @@
 /** GUI element that holds the drawing canvas. */
 public class DesktopView extends SurfaceView implements DesktopViewInterface,
         SurfaceHolder.Callback {
+    /** Used to define the animation feedback shown when a user touches the screen. */
+    public enum InputFeedbackType { NONE, SMALL_ANIMATION, LARGE_ANIMATION }
+
     private static final String TAG = "Chromoting";
 
     private final RenderData mRenderData;
-    private TouchInputHandlerInterface mInputHandler;
+    private final TouchInputHandlerInterface mInputHandler;
 
     /** The parent Desktop activity. */
     private Desktop mDesktop;
@@ -63,6 +66,9 @@
 
         private boolean mRunning = false;
 
+        /** Contains the size of the feedback animation for the most recent request. */
+        private float mFeedbackSizeInPixels;
+
         /** Lock to allow multithreaded access to {@link #mStartTime} and {@link #mRunning}. */
         private final Object mLock = new Object();
 
@@ -79,22 +85,29 @@
          * call {@link #render(Canvas, float, float, float)} periodically whilst
          * {@link #isAnimationRunning()} returns true.
          */
-        public void startAnimation() {
+        public void startAnimation(InputFeedbackType feedbackType) {
+            if (feedbackType == InputFeedbackType.NONE) {
+                return;
+            }
+
             synchronized (mLock) {
                 mRunning = true;
                 mStartTime = SystemClock.uptimeMillis();
+                mFeedbackSizeInPixels = getInputFeedbackSizeInPixels(feedbackType);
             }
         }
 
-        public void render(Canvas canvas, float x, float y, float size) {
+        public void render(Canvas canvas, float x, float y, float scale) {
             // |progress| is 0 at the beginning, 1 at the end.
             float progress;
+            float size;
             synchronized (mLock) {
                 progress = (SystemClock.uptimeMillis() - mStartTime) / TOTAL_DURATION_MS;
                 if (progress >= 1) {
                     mRunning = false;
                     return;
                 }
+                size = mFeedbackSizeInPixels / scale;
             }
 
             // Animation grows from 0 to |size|, and goes from fully opaque to transparent for a
@@ -111,6 +124,21 @@
                     new float[] {0.0f, 0.8f, 0.9f, 1.0f}, Shader.TileMode.CLAMP));
             canvas.drawCircle(x, y, radius, mPaint);
         }
+
+        private float getInputFeedbackSizeInPixels(InputFeedbackType feedbackType) {
+            switch (feedbackType) {
+                case SMALL_ANIMATION:
+                    return 40.0f;
+
+                case LARGE_ANIMATION:
+                    return 160.0f;
+
+                default:
+                    // Unreachable, but required by Google Java style and findbugs.
+                    assert false : "Unreached";
+                    return 0.0f;
+            }
+        }
     }
 
     private FeedbackAnimator mFeedbackAnimator = new FeedbackAnimator();
@@ -131,6 +159,10 @@
 
         mRenderData = new RenderData();
         mInputHandler = new TouchInputHandler(this, context, mRenderData);
+        // TODO(joedow): Move this into a method which will choose the correct input strategy
+        //               based on host support and current toggle setting in the UI.
+        mInputHandler.setInputStrategy(new TrackpadInputStrategy(this, mRenderData));
+
         mRepaintPending = false;
 
         getHolder().addCallback(this);
@@ -221,7 +253,7 @@
             synchronized (mRenderData) {
                 scaleFactor = mRenderData.transform.mapRadius(1);
             }
-            mFeedbackAnimator.render(canvas, x, y, 40 / scaleFactor);
+            mFeedbackAnimator.render(canvas, x, y, scaleFactor);
         }
 
         Bitmap cursorBitmap = JniInterface.getCursorBitmap();
@@ -327,46 +359,14 @@
     }
 
     @Override
-    public void injectMouseEvent(int x, int y, int button, boolean pressed) {
-        boolean cursorMoved = false;
-        synchronized (mRenderData) {
-            // Test if the cursor actually moved, which requires repainting the cursor. This
-            // requires that the TouchInputHandler doesn't mutate |mRenderData.cursorPosition|
-            // directly.
-            if (x != mRenderData.cursorPosition.x) {
-                mRenderData.cursorPosition.x = x;
-                cursorMoved = true;
-            }
-            if (y != mRenderData.cursorPosition.y) {
-                mRenderData.cursorPosition.y = y;
-                cursorMoved = true;
-            }
-        }
-
-        if (button == TouchInputHandler.BUTTON_UNDEFINED && !cursorMoved) {
-            // No need to inject anything or repaint.
-            return;
-        }
-
-        JniInterface.sendMouseEvent(x, y, button, pressed);
-        if (cursorMoved) {
-            // TODO(lambroslambrou): Optimize this by only repainting the affected areas.
+    public void showInputFeedback(InputFeedbackType feedbackToShow) {
+        if (feedbackToShow != InputFeedbackType.NONE) {
+            mFeedbackAnimator.startAnimation(feedbackToShow);
             requestRepaint();
         }
     }
 
     @Override
-    public void injectMouseWheelDeltaEvent(int deltaX, int deltaY) {
-        JniInterface.sendMouseWheelEvent(deltaX, deltaY);
-    }
-
-    @Override
-    public void showLongPressFeedback() {
-        mFeedbackAnimator.startAnimation();
-        requestRepaint();
-    }
-
-    @Override
     public void showActionBar() {
         mDesktop.showActionBar();
     }
diff --git a/remoting/android/java/src/org/chromium/chromoting/DesktopViewInterface.java b/remoting/android/java/src/org/chromium/chromoting/DesktopViewInterface.java
index 1dd0b82..b9d3147 100644
--- a/remoting/android/java/src/org/chromium/chromoting/DesktopViewInterface.java
+++ b/remoting/android/java/src/org/chromium/chromoting/DesktopViewInterface.java
@@ -8,14 +8,8 @@
  * Callback interface to allow the TouchInputHandler to request actions on the DesktopView.
  */
 public interface DesktopViewInterface {
-    /** Injects a mouse-move event, with optional button press/release. */
-    void injectMouseEvent(int x, int y, int button, boolean pressed);
-
-    /** Injects a mouse-wheel event with delta values. */
-    void injectMouseWheelDeltaEvent(int deltaX, int deltaY);
-
-    /** Triggers a brief cursor animation to indicate a long-press event. */
-    void showLongPressFeedback();
+    /** Triggers a brief animation to indicate the existence and location of an input event. */
+    void showInputFeedback(DesktopView.InputFeedbackType feedbackToShow);
 
     /** Shows the action bar. */
     void showActionBar();
diff --git a/remoting/android/java/src/org/chromium/chromoting/InputStrategyInterface.java b/remoting/android/java/src/org/chromium/chromoting/InputStrategyInterface.java
new file mode 100644
index 0000000..1048f51
--- /dev/null
+++ b/remoting/android/java/src/org/chromium/chromoting/InputStrategyInterface.java
@@ -0,0 +1,36 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chromoting;
+
+/**
+ * This interface defines the methods used to customize input handling for
+ * a particular strategy.  The implementing class is responsible for sending
+ * remote input events and defining implementation specific behavior.
+ */
+public interface InputStrategyInterface {
+    /** Sends a pointer move event to the remote host. */
+    void injectRemoteMoveEvent(int x, int y);
+
+    /** Sends a pointer button event to the remote host. */
+    void injectRemoteButtonEvent(int button, boolean pressed);
+
+    /** Sends a scroll/pan event to the remote host. */
+    void injectRemoteScrollEvent(int deltaX, int deltaY);
+
+    /** Returns the feedback animation type to use for a short press. */
+    DesktopView.InputFeedbackType getShortPressFeedbackType();
+
+    /** Returns the feedback animation type to use for a long press. */
+    DesktopView.InputFeedbackType getLongPressFeedbackType();
+
+    /**
+     * Indicates whether the view should be manipulated to keep the cursor in the center or if the
+     * view and cursor are not linked.
+     */
+    boolean centerCursorInView();
+
+    /** Indicates whether to invert cursor movement for panning/scrolling. */
+    boolean invertCursorMovement();
+}
diff --git a/remoting/android/java/src/org/chromium/chromoting/TouchInputHandler.java b/remoting/android/java/src/org/chromium/chromoting/TouchInputHandler.java
index 421c58c..d7520f7 100644
--- a/remoting/android/java/src/org/chromium/chromoting/TouchInputHandler.java
+++ b/remoting/android/java/src/org/chromium/chromoting/TouchInputHandler.java
@@ -8,14 +8,15 @@
 import android.graphics.Matrix;
 import android.graphics.PointF;
 import android.graphics.Rect;
-import android.graphics.RectF;
 import android.view.GestureDetector;
 import android.view.MotionEvent;
 import android.view.ScaleGestureDetector;
 import android.widget.Scroller;
 
 /**
- * This class implements the cursor-tracking behavior and gestures.
+ * This class is responsible for handling Touch input from the user.  Touch events which manipulate
+ * the local canvas are handled in this class and any input which should be sent to the remote host
+ * are passed to the InputStrategyInterface implementation set by the DesktopView.
  */
 public class TouchInputHandler implements TouchInputHandlerInterface {
     /**
@@ -24,13 +25,10 @@
      */
     private static final double MIN_ZOOM_DELTA = 0.05;
 
-    /**
-     * Maximum allowed zoom level - see {@link #repositionImageWithZoom()}.
-     */
-    private static final float MAX_ZOOM_FACTOR = 100.0f;
-
-    private DesktopViewInterface mViewer;
+    private final DesktopViewInterface mViewer;
     private final RenderData mRenderData;
+    private final DesktopCanvas mDesktopCanvas;
+    private InputStrategyInterface mInputStrategy;
 
     private GestureDetector mScroller;
     private ScaleGestureDetector mZoomer;
@@ -43,12 +41,6 @@
     private SwipePinchDetector mSwipePinchDetector;
 
     /**
-     * The current cursor position is stored here as floats, so that the desktop image can be
-     * positioned with sub-pixel accuracy, to give a smoother panning animation at high zoom levels.
-     */
-    private PointF mCursorPosition;
-
-    /**
      * Used for tracking swipe gestures. Only the Y-direction is needed for responding to swipe-up
      * or swipe-down.
      */
@@ -81,21 +73,10 @@
      */
     private boolean mSwipeCompleted = false;
 
-    /**
-     * Represents the amount of vertical space in pixels used by the soft input device and
-     * accompanying system UI.
-     */
-    private int mInputMethodOffsetY = 0;
-
-    /**
-     * Represents the amount of horizontal space in pixels used by the soft input device and
-     * accompanying system UI.
-     */
-    private int mInputMethodOffsetX = 0;
-
     public TouchInputHandler(DesktopViewInterface viewer, Context context, RenderData renderData) {
         mViewer = viewer;
         mRenderData = renderData;
+        mDesktopCanvas = new DesktopCanvas(mViewer, mRenderData);
 
         GestureListener listener = new GestureListener();
         mScroller = new GestureDetector(context, listener, null, false);
@@ -111,8 +92,6 @@
         mFlingScroller = new Scroller(context);
         mSwipePinchDetector = new SwipePinchDetector(context);
 
-        mCursorPosition = new PointF();
-
         // The threshold needs to be bigger than the ScaledTouchSlop used by the gesture-detectors,
         // so that a gesture cannot be both a tap and a swipe. It also needs to be small enough so
         // that intentional swipes are usually detected.
@@ -120,148 +99,6 @@
         mSwipeThreshold = 40 * density;
     }
 
-    /**
-     * Moves the mouse-cursor, injects a mouse-move event and repositions the image.
-     */
-    private void moveCursor(float newX, float newY) {
-        synchronized (mRenderData) {
-            // Constrain cursor to the image area.
-            if (newX < 0) newX = 0;
-            if (newY < 0) newY = 0;
-            if (newX > mRenderData.imageWidth) newX = mRenderData.imageWidth;
-            if (newY > mRenderData.imageHeight) newY = mRenderData.imageHeight;
-            mCursorPosition.set(newX, newY);
-            repositionImage();
-        }
-
-        mViewer.injectMouseEvent((int) newX, (int) newY, BUTTON_UNDEFINED, false);
-    }
-
-    /**
-     * Repositions the image by translating it (without affecting the zoom level) to place the
-     * cursor close to the center of the screen.
-     */
-    private void repositionImage() {
-        synchronized (mRenderData) {
-            float adjustedScreenWidth = mRenderData.screenWidth - mInputMethodOffsetX;
-            float adjustedScreenHeight = mRenderData.screenHeight - mInputMethodOffsetY;
-
-            // Get the current cursor position in screen coordinates.
-            float[] cursorScreen = {mCursorPosition.x, mCursorPosition.y};
-            mRenderData.transform.mapPoints(cursorScreen);
-
-            // Translate so the cursor is displayed in the middle of the screen.
-            mRenderData.transform.postTranslate(
-                    (float) adjustedScreenWidth / 2 - cursorScreen[0],
-                    (float) adjustedScreenHeight / 2 - cursorScreen[1]);
-
-            // Now the cursor is displayed in the middle of the screen, see if the image can be
-            // panned so that more of it is visible. The primary goal is to show as much of the
-            // image as possible. The secondary goal is to keep the cursor in the middle.
-
-            // Get the coordinates of the desktop rectangle (top-left/bottom-right corners) in
-            // screen coordinates. Order is: left, top, right, bottom.
-            RectF rectScreen = new RectF(0, 0, mRenderData.imageWidth, mRenderData.imageHeight);
-            mRenderData.transform.mapRect(rectScreen);
-
-            float leftDelta = rectScreen.left;
-            float rightDelta = rectScreen.right - mRenderData.screenWidth + mInputMethodOffsetX;
-            float topDelta = rectScreen.top;
-            float bottomDelta = rectScreen.bottom - mRenderData.screenHeight + mInputMethodOffsetY;
-            float xAdjust = 0;
-            float yAdjust = 0;
-
-            if (rectScreen.right - rectScreen.left < adjustedScreenWidth) {
-                // Image is narrower than the screen, so center it.
-                xAdjust = -(rightDelta + leftDelta) / 2;
-            } else if (leftDelta > 0 && rightDelta > 0) {
-                // Panning the image left will show more of it.
-                xAdjust = -Math.min(leftDelta, rightDelta);
-            } else if (leftDelta < 0 && rightDelta < 0) {
-                // Pan the image right.
-                xAdjust = Math.min(-leftDelta, -rightDelta);
-            }
-
-            // Apply similar logic for yAdjust.
-            if (rectScreen.bottom - rectScreen.top < adjustedScreenHeight) {
-                yAdjust = -(bottomDelta + topDelta) / 2;
-            } else if (topDelta > 0 && bottomDelta > 0) {
-                yAdjust = -Math.min(topDelta, bottomDelta);
-            } else if (topDelta < 0 && bottomDelta < 0) {
-                yAdjust = Math.min(-topDelta, -bottomDelta);
-            }
-
-            mRenderData.transform.postTranslate(xAdjust, yAdjust);
-        }
-        mViewer.transformationChanged();
-    }
-
-    /**
-     * Repositions the image by translating and zooming it, to keep the zoom level within sensible
-     * limits. The minimum zoom level is chosen to avoid black space around all 4 sides. The
-     * maximum zoom level is set arbitrarily, so that the user can zoom out again in a reasonable
-     * time, and to prevent arithmetic overflow problems from displaying the image.
-     */
-    private void repositionImageWithZoom() {
-        synchronized (mRenderData) {
-            // Avoid division by zero in case this gets called before the image size is initialized.
-            if (mRenderData.imageWidth == 0 || mRenderData.imageHeight == 0) {
-                return;
-            }
-
-            // Zoom out if the zoom level is too high.
-            float currentZoomLevel = mRenderData.transform.mapRadius(1.0f);
-            if (currentZoomLevel > MAX_ZOOM_FACTOR) {
-                mRenderData.transform.setScale(MAX_ZOOM_FACTOR, MAX_ZOOM_FACTOR);
-            }
-
-            // Get image size scaled to screen coordinates.
-            float[] imageSize = {mRenderData.imageWidth, mRenderData.imageHeight};
-            mRenderData.transform.mapVectors(imageSize);
-
-            if (imageSize[0] < mRenderData.screenWidth && imageSize[1] < mRenderData.screenHeight) {
-                // Displayed image is too small in both directions, so apply the minimum zoom
-                // level needed to fit either the width or height.
-                float scale = Math.min((float) mRenderData.screenWidth / mRenderData.imageWidth,
-                                       (float) mRenderData.screenHeight / mRenderData.imageHeight);
-                mRenderData.transform.setScale(scale, scale);
-            }
-
-            repositionImage();
-        }
-    }
-
-    /** Injects a button event using the current cursor location. */
-    private void injectButtonEvent(int button, boolean pressed) {
-        mViewer.injectMouseEvent((int) mCursorPosition.x, (int) mCursorPosition.y, button, pressed);
-    }
-
-    /** Processes a (multi-finger) swipe gesture. */
-    private boolean onSwipe() {
-        if (mTotalMotionY > mSwipeThreshold) {
-            // Swipe down occurred.
-            mViewer.showActionBar();
-        } else if (mTotalMotionY < -mSwipeThreshold) {
-            // Swipe up occurred.
-            mViewer.showKeyboard();
-        } else {
-            return false;
-        }
-
-        mSuppressCursorMovement = true;
-        mSuppressFling = true;
-        mSwipeCompleted = true;
-        return true;
-    }
-
-    /** Injects a button-up event if the button is currently held down (during a drag event). */
-    private void releaseAnyHeldButton() {
-        if (mHeldButton != BUTTON_UNDEFINED) {
-            injectButtonEvent(mHeldButton, false);
-            mHeldButton = BUTTON_UNDEFINED;
-        }
-    }
-
     @Override
     public boolean onTouchEvent(MotionEvent event) {
         // Avoid short-circuit logic evaluation - ensure all gesture detectors see all events so
@@ -295,28 +132,27 @@
 
     @Override
     public void onClientSizeChanged(int width, int height) {
-        repositionImageWithZoom();
+        mDesktopCanvas.repositionImageWithZoom();
     }
 
     @Override
     public void onHostSizeChanged(int width, int height) {
         moveCursor((float) width / 2, (float) height / 2);
-        repositionImageWithZoom();
+        mDesktopCanvas.resizeImageToFitScreen();
     }
 
     @Override
     public void onSoftInputMethodVisibilityChanged(boolean inputMethodVisible, Rect bounds) {
         synchronized (mRenderData) {
             if (inputMethodVisible) {
-                mInputMethodOffsetY = mRenderData.screenHeight - bounds.bottom;
-                mInputMethodOffsetX = mRenderData.screenWidth - bounds.right;
+                mDesktopCanvas.setInputMethodOffsetValues(mRenderData.screenWidth - bounds.right,
+                                                          mRenderData.screenHeight - bounds.bottom);
             } else {
-                mInputMethodOffsetY = 0;
-                mInputMethodOffsetX = 0;
+                mDesktopCanvas.setInputMethodOffsetValues(0, 0);
             }
         }
 
-        repositionImageWithZoom();
+        mDesktopCanvas.repositionImageWithZoom();
     }
 
     @Override
@@ -336,7 +172,74 @@
             canvasToImage.mapVectors(delta);
         }
 
-        moveCursor(mCursorPosition.x + delta[0], mCursorPosition.y + delta[1]);
+        moveCursorRelative(-delta[0], -delta[1]);
+    }
+
+    @Override
+    public void setInputStrategy(InputStrategyInterface inputStrategy) {
+        mInputStrategy = inputStrategy;
+        mDesktopCanvas.setCenterCursorInView(mInputStrategy.centerCursorInView());
+    }
+
+    /** Moves the mouse-cursor relative to the current position. */
+    private void moveCursorRelative(float deltaX, float deltaY) {
+        if (mInputStrategy.invertCursorMovement()) {
+            deltaX = -deltaX;
+            deltaY = -deltaY;
+        }
+
+        PointF cursorPosition = mDesktopCanvas.getCursorPosition();
+        moveCursor(cursorPosition.x + deltaX, cursorPosition.y + deltaY);
+    }
+
+    /** Moves the mouse-cursor, injects a mouse-move event and repositions the image. */
+    private void moveCursor(float newX, float newY) {
+        synchronized (mRenderData) {
+            // Constrain cursor to the image area.
+            if (newX < 0) {
+                newX = 0;
+            } else if (newX > mRenderData.imageWidth) {
+                newX = mRenderData.imageWidth;
+            }
+
+            if (newY < 0) {
+                newY = 0;
+            } else if (newY > mRenderData.imageHeight) {
+                newY = mRenderData.imageHeight;
+            }
+
+            mDesktopCanvas.setCursorPosition(newX, newY);
+        }
+
+        mDesktopCanvas.repositionImage();
+
+        mInputStrategy.injectRemoteMoveEvent((int) newX, (int) newY);
+    }
+
+    /** Processes a (multi-finger) swipe gesture. */
+    private boolean onSwipe() {
+        if (mTotalMotionY > mSwipeThreshold) {
+            // Swipe down occurred.
+            mViewer.showActionBar();
+        } else if (mTotalMotionY < -mSwipeThreshold) {
+            // Swipe up occurred.
+            mViewer.showKeyboard();
+        } else {
+            return false;
+        }
+
+        mSuppressCursorMovement = true;
+        mSuppressFling = true;
+        mSwipeCompleted = true;
+        return true;
+    }
+
+    /** Injects a button-up event if the button is currently held down (during a drag event). */
+    private void releaseAnyHeldButton() {
+        if (mHeldButton != BUTTON_UNDEFINED) {
+            mInputStrategy.injectRemoteButtonEvent(mHeldButton, false);
+            mHeldButton = BUTTON_UNDEFINED;
+        }
     }
 
     /** Responds to touch events filtered by the gesture detectors. */
@@ -358,7 +261,7 @@
             }
 
             if (pointerCount == 2 && mSwipePinchDetector.isSwiping()) {
-                mViewer.injectMouseWheelDeltaEvent(-(int) distanceX, -(int) distanceY);
+                mInputStrategy.injectRemoteScrollEvent(-(int) distanceX, -(int) distanceY);
 
                 // Prevent the cursor being moved or flung by the gesture.
                 mSuppressCursorMovement = true;
@@ -376,7 +279,7 @@
                 canvasToImage.mapVectors(delta);
             }
 
-            moveCursor(mCursorPosition.x - delta[0], mCursorPosition.y - delta[1]);
+            moveCursorRelative(delta[0], delta[1]);
             return true;
         }
 
@@ -425,7 +328,8 @@
                 mRenderData.transform.postScale(
                         scaleFactor, scaleFactor, detector.getFocusX(), detector.getFocusY());
             }
-            repositionImageWithZoom();
+            mDesktopCanvas.repositionImageWithZoom();
+
             return true;
         }
 
@@ -450,6 +354,31 @@
             onScale(detector);
         }
 
+        /** Called when the user taps the screen with one or more fingers. */
+        @Override
+        public boolean onTap(int pointerCount) {
+            int button = mouseButtonFromPointerCount(pointerCount);
+            if (button == BUTTON_UNDEFINED) {
+                return false;
+            } else {
+                mInputStrategy.injectRemoteButtonEvent(button, true);
+                mInputStrategy.injectRemoteButtonEvent(button, false);
+                mViewer.showInputFeedback(mInputStrategy.getShortPressFeedbackType());
+                return true;
+            }
+        }
+
+        /** Called when a long-press is triggered for one or more fingers. */
+        @Override
+        public void onLongPress(int pointerCount) {
+            mHeldButton = mouseButtonFromPointerCount(pointerCount);
+            if (mHeldButton != BUTTON_UNDEFINED) {
+                mInputStrategy.injectRemoteButtonEvent(mHeldButton, true);
+                mViewer.showInputFeedback(mInputStrategy.getLongPressFeedbackType());
+                mSuppressFling = true;
+            }
+        }
+
         /** Maps the number of fingers in a tap or long-press gesture to a mouse-button. */
         private int mouseButtonFromPointerCount(int pointerCount) {
             switch (pointerCount) {
@@ -463,29 +392,5 @@
                     return BUTTON_UNDEFINED;
             }
         }
-
-        /** Called when the user taps the screen with one or more fingers. */
-        @Override
-        public boolean onTap(int pointerCount) {
-            int button = mouseButtonFromPointerCount(pointerCount);
-            if (button == BUTTON_UNDEFINED) {
-                return false;
-            } else {
-                injectButtonEvent(button, true);
-                injectButtonEvent(button, false);
-                return true;
-            }
-        }
-
-        /** Called when a long-press is triggered for one or more fingers. */
-        @Override
-        public void onLongPress(int pointerCount) {
-            mHeldButton = mouseButtonFromPointerCount(pointerCount);
-            if (mHeldButton != BUTTON_UNDEFINED) {
-                injectButtonEvent(mHeldButton, true);
-                mViewer.showLongPressFeedback();
-                mSuppressFling = true;
-            }
-        }
     }
 }
diff --git a/remoting/android/java/src/org/chromium/chromoting/TouchInputHandlerInterface.java b/remoting/android/java/src/org/chromium/chromoting/TouchInputHandlerInterface.java
index 8bba3287..80bd162 100644
--- a/remoting/android/java/src/org/chromium/chromoting/TouchInputHandlerInterface.java
+++ b/remoting/android/java/src/org/chromium/chromoting/TouchInputHandlerInterface.java
@@ -15,7 +15,7 @@
  * showing/hiding UI elements). All methods are called on the main UI thread.
  */
 public interface TouchInputHandlerInterface {
-    // These constants must match those in the generated struct protoc::MouseEvent_MouseButton.
+    // These constants must match those in the generated struct protocol::MouseEvent_MouseButton.
     int BUTTON_UNDEFINED = 0;
     int BUTTON_LEFT = 1;
     int BUTTON_MIDDLE = 2;
@@ -52,4 +52,7 @@
      * cancelled. After this method returns, the DesktopView will schedule a repaint.
      */
     void processAnimation();
+
+    /** Sets the underlying strategy to use when translating and forwarding local touch input. */
+    void setInputStrategy(InputStrategyInterface inputStrategy);
 }
diff --git a/remoting/android/java/src/org/chromium/chromoting/TrackpadInputStrategy.java b/remoting/android/java/src/org/chromium/chromoting/TrackpadInputStrategy.java
new file mode 100644
index 0000000..edc9baf
--- /dev/null
+++ b/remoting/android/java/src/org/chromium/chromoting/TrackpadInputStrategy.java
@@ -0,0 +1,90 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chromoting;
+
+import org.chromium.chromoting.jni.JniInterface;
+
+/**
+ * Defines a set of behavior and methods to simulate trackpad behavior when responding to
+ * local input event data.  This class is also responsible for forwarding input event data
+ * to the remote host for injection there.
+ */
+public class TrackpadInputStrategy implements InputStrategyInterface {
+    private final RenderData mRenderData;
+    private final DesktopViewInterface mViewer;
+
+    public TrackpadInputStrategy(DesktopViewInterface viewer, RenderData renderData) {
+        mViewer = viewer;
+        mRenderData = renderData;
+    }
+
+    @Override
+    public void injectRemoteMoveEvent(int x, int y) {
+        injectRemoteButtonEvent(x, y, TouchInputHandlerInterface.BUTTON_UNDEFINED, false);
+    }
+
+    @Override
+    public void injectRemoteButtonEvent(int button, boolean pressed) {
+        int x;
+        int y;
+        synchronized (mRenderData) {
+            x = mRenderData.cursorPosition.x;
+            y = mRenderData.cursorPosition.y;
+        }
+
+        injectRemoteButtonEvent(x, y, button, pressed);
+    }
+
+    @Override
+    public void injectRemoteScrollEvent(int deltaX, int deltaY) {
+        JniInterface.sendMouseWheelEvent(deltaX, deltaY);
+    }
+
+    @Override
+    public DesktopView.InputFeedbackType getShortPressFeedbackType() {
+        return DesktopView.InputFeedbackType.NONE;
+    }
+
+    @Override
+    public DesktopView.InputFeedbackType getLongPressFeedbackType() {
+        return DesktopView.InputFeedbackType.SMALL_ANIMATION;
+    }
+
+    @Override
+    public boolean centerCursorInView() {
+        return true;
+    }
+
+    @Override
+    public boolean invertCursorMovement() {
+        return true;
+    }
+
+    private void injectRemoteButtonEvent(int x, int y, int button, boolean pressed) {
+        boolean cursorMoved = false;
+        synchronized (mRenderData) {
+            // Test if the cursor actually moved, which requires repainting the cursor. This
+            // requires that |mRenderData.cursorPosition| was not assigned to beforehand.
+            if (x != mRenderData.cursorPosition.x) {
+                mRenderData.cursorPosition.x = x;
+                cursorMoved = true;
+            }
+            if (y != mRenderData.cursorPosition.y) {
+                mRenderData.cursorPosition.y = y;
+                cursorMoved = true;
+            }
+        }
+
+        if (button == TouchInputHandlerInterface.BUTTON_UNDEFINED && !cursorMoved) {
+            // No need to inject anything or repaint.
+            return;
+        }
+
+        JniInterface.sendMouseEvent(x, y, button, pressed);
+        if (cursorMoved) {
+            mViewer.transformationChanged();
+        }
+    }
+}
diff --git a/sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc b/sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc
index 8c679a3..8bfb025b 100644
--- a/sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc
+++ b/sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc
@@ -21,6 +21,10 @@
 #include "sandbox/linux/services/syscall_wrappers.h"
 #include "sandbox/linux/system_headers/linux_syscalls.h"
 
+#if !defined(SO_PEEK_OFF)
+#define SO_PEEK_OFF 42
+#endif
+
 // Changing this implementation will have an effect on *all* policies.
 // Currently this means: Renderer/Worker, GPU, Flash and NaCl.
 
@@ -227,6 +231,16 @@
     return RestrictSocketcallCommand();
 #endif
 
+#if defined(__x86_64__)
+  if (sysno == __NR_getsockopt || sysno ==__NR_setsockopt) {
+    // Used by Mojo EDK to catch a message pipe being sent over itself.
+    const Arg<int> level(1);
+    const Arg<int> optname(2);
+    return If(level == SOL_SOCKET && optname == SO_PEEK_OFF,
+              Allow()).Else(CrashSIGSYS());
+  }
+#endif
+
   if (IsBaselinePolicyWatched(sysno)) {
     // Previously unseen syscalls. TODO(jln): some of these should
     // be denied gracefully right away.
diff --git a/sandbox/linux/seccomp-bpf-helpers/baseline_policy_unittest.cc b/sandbox/linux/seccomp-bpf-helpers/baseline_policy_unittest.cc
index 614849f..7ece8be 100644
--- a/sandbox/linux/seccomp-bpf-helpers/baseline_policy_unittest.cc
+++ b/sandbox/linux/seccomp-bpf-helpers/baseline_policy_unittest.cc
@@ -6,6 +6,7 @@
 
 #include <errno.h>
 #include <fcntl.h>
+#include <netinet/in.h>
 #include <sched.h>
 #include <signal.h>
 #include <string.h>
@@ -36,6 +37,10 @@
 #include "sandbox/linux/tests/test_utils.h"
 #include "sandbox/linux/tests/unit_tests.h"
 
+#if !defined(SO_PEEK_OFF)
+#define SO_PEEK_OFF 42
+#endif
+
 namespace sandbox {
 
 namespace {
@@ -329,6 +334,51 @@
   clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
 }
 
+#if defined(__x86_64__)
+BPF_DEATH_TEST_C(BaselinePolicy,
+                 GetSockOptWrongLevelSigsys,
+                 DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()),
+                 BaselinePolicy) {
+  int fds[2];
+  PCHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == 0);
+  int id;
+  socklen_t peek_off_size = sizeof(id);
+  getsockopt(fds[0], IPPROTO_TCP, SO_PEEK_OFF, &id, &peek_off_size);
+}
+
+BPF_DEATH_TEST_C(BaselinePolicy,
+                 GetSockOptWrongOptionSigsys,
+                 DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()),
+                 BaselinePolicy) {
+  int fds[2];
+  PCHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == 0);
+  int id;
+  socklen_t peek_off_size = sizeof(id);
+  getsockopt(fds[0], SOL_SOCKET, SO_DEBUG, &id, &peek_off_size);
+}
+
+BPF_DEATH_TEST_C(BaselinePolicy,
+                 SetSockOptWrongLevelSigsys,
+                 DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()),
+                 BaselinePolicy) {
+  int fds[2];
+  PCHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == 0);
+  int id;
+  setsockopt(fds[0], IPPROTO_TCP, SO_PEEK_OFF, &id, sizeof(id));
+}
+
+
+BPF_DEATH_TEST_C(BaselinePolicy,
+                 SetSockOptWrongOptionSigsys,
+                 DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()),
+                 BaselinePolicy) {
+  int fds[2];
+  PCHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == 0);
+  int id;
+  setsockopt(fds[0], SOL_SOCKET, SO_DEBUG, &id, sizeof(id));
+}
+#endif
+
 }  // namespace
 
 }  // namespace sandbox
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index 25b01660..5fbc1d34 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -503,6 +503,9 @@
       {
         "isolate_name": "telemetry_gpu_unittests",
         "name": "telemetry_gpu_unittests",
+        "override_compile_targets": [
+          "telemetry_gpu_unittests_run"
+        ],
         "swarming": {
           "can_use_on_swarming_builders": true
         }
@@ -510,6 +513,9 @@
       {
         "isolate_name": "telemetry_perf_unittests",
         "name": "telemetry_perf_unittests",
+        "override_compile_targets": [
+          "telemetry_perf_unittests_run"
+        ],
         "swarming": {
           "can_use_on_swarming_builders": true
         }
@@ -1430,6 +1436,9 @@
       {
         "isolate_name": "telemetry_gpu_unittests",
         "name": "telemetry_gpu_unittests",
+        "override_compile_targets": [
+          "telemetry_gpu_unittests_run"
+        ],
         "swarming": {
           "can_use_on_swarming_builders": true
         }
@@ -1437,6 +1446,9 @@
       {
         "isolate_name": "telemetry_perf_unittests",
         "name": "telemetry_perf_unittests",
+        "override_compile_targets": [
+          "telemetry_perf_unittests_run"
+        ],
         "swarming": {
           "can_use_on_swarming_builders": true
         }
@@ -1644,6 +1656,9 @@
       {
         "isolate_name": "telemetry_gpu_unittests",
         "name": "telemetry_gpu_unittests",
+        "override_compile_targets": [
+          "telemetry_gpu_unittests_run"
+        ],
         "swarming": {
           "can_use_on_swarming_builders": true
         }
@@ -1651,6 +1666,9 @@
       {
         "isolate_name": "telemetry_perf_unittests",
         "name": "telemetry_perf_unittests",
+        "override_compile_targets": [
+          "telemetry_perf_unittests_run"
+        ],
         "swarming": {
           "can_use_on_swarming_builders": true
         }
@@ -4739,6 +4757,9 @@
       {
         "isolate_name": "telemetry_gpu_unittests",
         "name": "telemetry_gpu_unittests",
+        "override_compile_targets": [
+          "telemetry_gpu_unittests_run"
+        ],
         "swarming": {
           "can_use_on_swarming_builders": true
         }
@@ -4746,6 +4767,9 @@
       {
         "isolate_name": "telemetry_perf_unittests",
         "name": "telemetry_perf_unittests",
+        "override_compile_targets": [
+          "telemetry_perf_unittests_run"
+        ],
         "swarming": {
           "can_use_on_swarming_builders": true
         }
@@ -4937,6 +4961,9 @@
       {
         "isolate_name": "telemetry_gpu_unittests",
         "name": "telemetry_gpu_unittests",
+        "override_compile_targets": [
+          "telemetry_gpu_unittests_run"
+        ],
         "swarming": {
           "can_use_on_swarming_builders": true
         }
@@ -4944,6 +4971,9 @@
       {
         "isolate_name": "telemetry_perf_unittests",
         "name": "telemetry_perf_unittests",
+        "override_compile_targets": [
+          "telemetry_perf_unittests_run"
+        ],
         "swarming": {
           "can_use_on_swarming_builders": true
         }
@@ -5240,6 +5270,9 @@
       {
         "isolate_name": "telemetry_gpu_unittests",
         "name": "telemetry_gpu_unittests",
+        "override_compile_targets": [
+          "telemetry_gpu_unittests_run"
+        ],
         "swarming": {
           "can_use_on_swarming_builders": true
         }
@@ -5247,6 +5280,9 @@
       {
         "isolate_name": "telemetry_perf_unittests",
         "name": "telemetry_perf_unittests",
+        "override_compile_targets": [
+          "telemetry_perf_unittests_run"
+        ],
         "swarming": {
           "can_use_on_swarming_builders": true
         }
@@ -5426,6 +5462,9 @@
       {
         "isolate_name": "telemetry_gpu_unittests",
         "name": "telemetry_gpu_unittests",
+        "override_compile_targets": [
+          "telemetry_gpu_unittests_run"
+        ],
         "swarming": {
           "can_use_on_swarming_builders": true
         }
@@ -5433,6 +5472,9 @@
       {
         "isolate_name": "telemetry_perf_unittests",
         "name": "telemetry_perf_unittests",
+        "override_compile_targets": [
+          "telemetry_perf_unittests_run"
+        ],
         "swarming": {
           "can_use_on_swarming_builders": true
         }
diff --git a/testing/buildbot/chromium.json b/testing/buildbot/chromium.json
index 47e8916e..e4bdc07 100644
--- a/testing/buildbot/chromium.json
+++ b/testing/buildbot/chromium.json
@@ -1,4 +1,26 @@
 {
+  "Linux": {
+    "additional_compile_targets": [
+      "all"
+    ],
+    "scripts": [
+      {
+        "name": "checklicenses",
+        "script": "checklicenses.py"
+      },
+      {
+        "name": "checkperms",
+        "script": "checkperms.py"
+      },
+      {
+        "args": [
+          "linux-release/sizes"
+        ],
+        "name": "sizes",
+        "script": "sizes.py"
+      }
+    ]
+  },
   "Linux x64": {
     "additional_compile_targets": [
       "all"
diff --git a/testing/buildbot/chromium.linux.json b/testing/buildbot/chromium.linux.json
index 9caca88..ed24041 100644
--- a/testing/buildbot/chromium.linux.json
+++ b/testing/buildbot/chromium.linux.json
@@ -673,6 +673,9 @@
       {
         "isolate_name": "telemetry_gpu_unittests",
         "name": "telemetry_gpu_unittests",
+        "override_compile_targets": [
+          "telemetry_gpu_unittests_run"
+        ],
         "swarming": {
           "can_use_on_swarming_builders": true
         }
@@ -680,6 +683,9 @@
       {
         "isolate_name": "telemetry_perf_unittests",
         "name": "telemetry_perf_unittests",
+        "override_compile_targets": [
+          "telemetry_perf_unittests_run"
+        ],
         "swarming": {
           "can_use_on_swarming_builders": true
         }
@@ -1045,6 +1051,9 @@
       {
         "isolate_name": "telemetry_gpu_unittests",
         "name": "telemetry_gpu_unittests",
+        "override_compile_targets": [
+          "telemetry_gpu_unittests_run"
+        ],
         "swarming": {
           "can_use_on_swarming_builders": true
         }
@@ -1052,6 +1061,9 @@
       {
         "isolate_name": "telemetry_perf_unittests",
         "name": "telemetry_perf_unittests",
+        "override_compile_targets": [
+          "telemetry_perf_unittests_run"
+        ],
         "swarming": {
           "can_use_on_swarming_builders": true
         }
diff --git a/testing/buildbot/chromium.mac.json b/testing/buildbot/chromium.mac.json
index afc8c09..2da7a3f 100644
--- a/testing/buildbot/chromium.mac.json
+++ b/testing/buildbot/chromium.mac.json
@@ -318,6 +318,9 @@
       {
         "isolate_name": "telemetry_gpu_unittests",
         "name": "telemetry_gpu_unittests",
+        "override_compile_targets": [
+          "telemetry_gpu_unittests_run"
+        ],
         "swarming": {
           "can_use_on_swarming_builders": true
         }
@@ -325,6 +328,9 @@
       {
         "isolate_name": "telemetry_perf_unittests",
         "name": "telemetry_perf_unittests",
+        "override_compile_targets": [
+          "telemetry_perf_unittests_run"
+        ],
         "swarming": {
           "can_use_on_swarming_builders": true
         }
@@ -613,6 +619,9 @@
       {
         "isolate_name": "telemetry_gpu_unittests",
         "name": "telemetry_gpu_unittests",
+        "override_compile_targets": [
+          "telemetry_gpu_unittests_run"
+        ],
         "swarming": {
           "can_use_on_swarming_builders": true
         }
@@ -620,6 +629,9 @@
       {
         "isolate_name": "telemetry_perf_unittests",
         "name": "telemetry_perf_unittests",
+        "override_compile_targets": [
+          "telemetry_perf_unittests_run"
+        ],
         "swarming": {
           "can_use_on_swarming_builders": true
         }
@@ -908,6 +920,9 @@
       {
         "isolate_name": "telemetry_gpu_unittests",
         "name": "telemetry_gpu_unittests",
+        "override_compile_targets": [
+          "telemetry_gpu_unittests_run"
+        ],
         "swarming": {
           "can_use_on_swarming_builders": true
         }
@@ -915,6 +930,9 @@
       {
         "isolate_name": "telemetry_perf_unittests",
         "name": "telemetry_perf_unittests",
+        "override_compile_targets": [
+          "telemetry_perf_unittests_run"
+        ],
         "swarming": {
           "can_use_on_swarming_builders": true
         }
@@ -1203,6 +1221,9 @@
       {
         "isolate_name": "telemetry_gpu_unittests",
         "name": "telemetry_gpu_unittests",
+        "override_compile_targets": [
+          "telemetry_gpu_unittests_run"
+        ],
         "swarming": {
           "can_use_on_swarming_builders": true
         }
@@ -1210,6 +1231,9 @@
       {
         "isolate_name": "telemetry_perf_unittests",
         "name": "telemetry_perf_unittests",
+        "override_compile_targets": [
+          "telemetry_perf_unittests_run"
+        ],
         "swarming": {
           "can_use_on_swarming_builders": true
         }
@@ -1499,6 +1523,19 @@
       {
         "isolate_name": "telemetry_gpu_unittests",
         "name": "telemetry_gpu_unittests",
+        "override_compile_targets": [
+          "telemetry_gpu_unittests_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        }
+      },
+      {
+        "isolate_name": "telemetry_perf_unittests",
+        "name": "telemetry_perf_unittests",
+        "override_compile_targets": [
+          "telemetry_perf_unittests_run"
+        ],
         "swarming": {
           "can_use_on_swarming_builders": true
         }
@@ -1510,10 +1547,6 @@
         "script": "telemetry_unittests.py"
       },
       {
-        "name": "telemetry_perf_unittests",
-        "script": "telemetry_perf_unittests.py"
-      },
-      {
         "name": "nacl_integration",
         "script": "nacl_integration.py"
       }
diff --git a/testing/buildbot/chromium.win.json b/testing/buildbot/chromium.win.json
index f4e68fa4..cc97231 100644
--- a/testing/buildbot/chromium.win.json
+++ b/testing/buildbot/chromium.win.json
@@ -690,6 +690,9 @@
       {
         "isolate_name": "telemetry_gpu_unittests",
         "name": "telemetry_gpu_unittests",
+        "override_compile_targets": [
+          "telemetry_gpu_unittests_run"
+        ],
         "swarming": {
           "can_use_on_swarming_builders": true
         }
@@ -697,6 +700,9 @@
       {
         "isolate_name": "telemetry_perf_unittests",
         "name": "telemetry_perf_unittests",
+        "override_compile_targets": [
+          "telemetry_perf_unittests_run"
+        ],
         "swarming": {
           "can_use_on_swarming_builders": true
         }
@@ -1138,6 +1144,9 @@
       {
         "isolate_name": "telemetry_gpu_unittests",
         "name": "telemetry_gpu_unittests",
+        "override_compile_targets": [
+          "telemetry_gpu_unittests_run"
+        ],
         "swarming": {
           "can_use_on_swarming_builders": true
         }
@@ -1145,6 +1154,9 @@
       {
         "isolate_name": "telemetry_perf_unittests",
         "name": "telemetry_perf_unittests",
+        "override_compile_targets": [
+          "telemetry_perf_unittests_run"
+        ],
         "swarming": {
           "can_use_on_swarming_builders": true
         }
@@ -1490,6 +1502,19 @@
       {
         "isolate_name": "telemetry_gpu_unittests",
         "name": "telemetry_gpu_unittests",
+        "override_compile_targets": [
+          "telemetry_gpu_unittests_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        }
+      },
+      {
+        "isolate_name": "telemetry_perf_unittests",
+        "name": "telemetry_perf_unittests",
+        "override_compile_targets": [
+          "telemetry_perf_unittests_run"
+        ],
         "swarming": {
           "can_use_on_swarming_builders": true
         }
@@ -1499,10 +1524,6 @@
       {
         "name": "telemetry_unittests",
         "script": "telemetry_unittests.py"
-      },
-      {
-        "name": "telemetry_perf_unittests",
-        "script": "telemetry_perf_unittests.py"
       }
     ]
   },
@@ -1974,6 +1995,9 @@
       {
         "isolate_name": "telemetry_gpu_unittests",
         "name": "telemetry_gpu_unittests",
+        "override_compile_targets": [
+          "telemetry_gpu_unittests_run"
+        ],
         "swarming": {
           "can_use_on_swarming_builders": true
         }
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index a1dae79..49c7233 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -258,6 +258,8 @@
 
 crbug.com/535408 fast/js/function-bind.html [ NeedsManualRebaseline ]
 
+crbug.com/334828 fast/box-shadow/inset-subpixel.html [ NeedsRebaseline ]
+
 crbug.com/552574 fast/js/regexp-caching.html [ NeedsManualRebaseline ]
 
 crbug.com/498539 http/tests/inspector/elements/styles/selector-line.html [ Pass Timeout ]
@@ -1359,5 +1361,3 @@
 crbug.com/548765 http/tests/inspector/console-fetch-logging.html [ Failure Pass Slow ]
 
 crbug.com/549314 [ XP ] inspector-protocol/layout-fonts/unicode-range-combining-chars-fallback.html [ Failure ]
-
-crbug.com/555052 http/tests/misc/script-sync-slow-scripts-onerror.html [ Failure Pass ]
diff --git a/third_party/WebKit/LayoutTests/fast/box-shadow/degenerate-radius-crash-expected.txt b/third_party/WebKit/LayoutTests/fast/box-shadow/degenerate-radius-crash-expected.txt
new file mode 100644
index 0000000..9b9c9725
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/box-shadow/degenerate-radius-crash-expected.txt
@@ -0,0 +1 @@
+PASS: did not crash.
diff --git a/third_party/WebKit/LayoutTests/fast/box-shadow/degenerate-radius-crash.html b/third_party/WebKit/LayoutTests/fast/box-shadow/degenerate-radius-crash.html
new file mode 100644
index 0000000..9763d32
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/box-shadow/degenerate-radius-crash.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<head>
+
+<style>
+div {
+    width: 200px;
+    height: 100px;
+}
+
+.negative {
+    box-shadow: 3px 3px -10px;
+}
+
+.negative-inset {
+    box-shadow: 3px 3px -10px inset;
+}
+
+.overflow {
+    box-shadow: 3px 3px 100000000000000000000000000px;
+}
+
+.overflow-inset {
+    box-shadow: 3px 3px 100000000000000000000000000px inset;
+}
+
+</style>
+</head>
+
+<body>
+  <!-- Test for crbug.com/424119 -->
+  <div class="negative"></div>
+  <div class="negative-inset"></div>
+  <div class="overflow"></div>
+  <div class="overflow-inset"></div>
+
+  PASS: did not crash.
+
+  <script>
+    if (window.testRunner)
+      testRunner.dumpAsText();
+  </script>
+</body>
diff --git a/third_party/WebKit/LayoutTests/fast/box-shadow/inset-subpixel.html b/third_party/WebKit/LayoutTests/fast/box-shadow/inset-subpixel.html
new file mode 100644
index 0000000..5567c4c9
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/box-shadow/inset-subpixel.html
@@ -0,0 +1,40 @@
+<style>
+    div.square {
+        width: 80px;
+        height: 80px;
+        margin: 10px;
+        display: inline-block;
+        background: lightyellow;
+        border: 10px solid green;
+    }
+    .rounded div.square {
+        -webkit-border-radius: 20px;
+    }
+</style>
+<div>
+    <div class="square" style="-webkit-box-shadow: rgba(0, 0, 0, 0.2) 15.5px 15.5px inset;"></div>
+    <div class="square" style="-webkit-box-shadow: -15px 15px 0 5.5px rgba(0, 0, 0, 0.2) inset;"></div>
+    <div class="square" style="-webkit-box-shadow: inset rgba(0, 0, 0, 0.2) 15.5px -15.5px 0 -10px;"></div>
+    <div class="square" style="-webkit-box-shadow: inset -15.5px -15.5px 5.5px rgba(0, 0, 0, 0.2);"></div>
+    <div class="square" style="-webkit-box-shadow: rgba(0, 0, 0, 0.2) inset -15.5px -15.5px 5.5px;"></div>
+</div>
+<div class="rounded">
+    <div class="square" style="-webkit-box-shadow: rgba(0, 0, 0, 0.2) 15.5px 15.5px inset;"></div>
+    <div class="square" style="-webkit-box-shadow: rgba(0, 0, 0, 0.2) -15px 15px 0 5.5px inset;"></div>
+    <div class="square" style="-webkit-box-shadow: rgba(0, 0, 0, 0.2) 15.5px -15.5px 0 -10px inset;"></div>
+    <div class="square" style="-webkit-box-shadow: rgba(0, 0, 0, 0.2) -15.5px -15.5px 5.5px inset;"></div>
+    <div class="square" style="-webkit-box-shadow: rgba(0, 0, 0, 0.2) -15.5px -15.5px inset, rgba(0, 0, 127, 0.6) 5px 5px 5px inset; border-style: dashed;"></div>
+</div>
+<div style="width: 600px; text-align: center;">
+    <span style="
+        padding: 0 15px;
+        font-size: 72px;
+        background-color: lightyellow;
+        -webkit-border-radius: 10px;
+        border: 5px solid green;
+        line-height: 1.5;
+        -webkit-box-shadow: 15px 15px 5px rgba(0, 0, 0, 0.2) inset;
+    ">
+        This sentence is too long to fit on a single line.
+    </span>
+</div>
diff --git a/third_party/WebKit/LayoutTests/fast/domurl/resources/urlsearchparams-worker.js b/third_party/WebKit/LayoutTests/fast/domurl/resources/urlsearchparams-worker.js
new file mode 100644
index 0000000..999ddfc
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/domurl/resources/urlsearchparams-worker.js
@@ -0,0 +1,14 @@
+importScripts("../../../resources/testharness.js")
+
+test(function() {
+    assert_true('URLSearchParams' in self);
+    assert_true('toString' in URLSearchParams.prototype);
+    assert_true('append' in URLSearchParams.prototype);
+    assert_true('delete' in URLSearchParams.prototype);
+    assert_true('get' in URLSearchParams.prototype);
+    assert_true('getAll' in URLSearchParams.prototype);
+    assert_true('has' in URLSearchParams.prototype);
+    assert_true('set' in URLSearchParams.prototype);
+}, 'URLSearchParams interface');
+
+done();
diff --git a/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-append.html b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-append.html
new file mode 100644
index 0000000..74071f1a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-append.html
@@ -0,0 +1,51 @@
+<!doctype html>
+<html>
+<head>
+<meta charset="utf8">
+<link rel="help" href="https://url.spec.whatwg.org/#dom-urlsearchparams-append">
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script src="resources/testharness-extras.js"></script>
+<script>
+test(function() {
+    var params = new URLSearchParams();
+    params.append('a', 'b');
+    assert_equals(params + '', 'a=b');
+    params.append('a', 'b');
+    assert_equals(params + '', 'a=b&a=b');
+    params.append('a', 'c');
+    assert_equals(params + '', 'a=b&a=b&a=c');
+}, 'Append same name');
+
+test(function() {
+    var params = new URLSearchParams();
+    params.append('', '');
+    assert_equals(params + '', '=');
+    params.append('', '');
+    assert_equals(params + '', '=&=');
+}, 'Append empty strings');
+
+test(function() {
+    var params = new URLSearchParams();
+    params.append(null, null);
+    assert_equals(params + '', 'null=null');
+    params.append(null, null);
+    assert_equals(params + '', 'null=null&null=null');
+}, 'Append null');
+
+test(function() {
+    var params = new URLSearchParams();
+    params.append('first', 1);
+    params.append('second', 2);
+    params.append('third', '');
+    params.append('first', 10);
+    assert_true(params.has('first'), 'Search params object has name "first"');
+    assert_equals(params.get('first'), '1', 'Search params object has name "first" with value "1"');
+    assert_equals(params.get('second'), '2', 'Search params object has name "second" with value "2"');
+    assert_equals(params.get('third'), '', 'Search params object has name "third" with value ""');
+    params.append('first', 10);
+    assert_equals(params.get('first'), '1', 'Search params object has name "first" with value "1"');
+}, 'Append multiple');
+</script>
+</head>
+</html>
diff --git a/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-constructor.html b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-constructor.html
new file mode 100644
index 0000000..33a446e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-constructor.html
@@ -0,0 +1,163 @@
+<!doctype html>
+<html>
+<head>
+<meta charset="utf8">
+<link rel="help" href="https://url.spec.whatwg.org/#urlsearchparams">
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script src="resources/testharness-extras.js"></script>
+<script>
+function assert_type_error(f, msg) {
+    assert_throws(TypeError(), f, msg);
+}
+
+// Consider upstreaming something kinda like this.
+function assert_iteration_equals(iteration, expectation) {
+    var actual = [...iteration];
+    assert_equals(actual.length, expectation.length);
+    for (var i = 0; i < actual.length; i++) {
+        assert_equals(typeof actual[i], typeof expectation[i]);
+        if (actual[i] instanceof Array)
+            assert_array_equals(actual[i], expectation[i]);
+        else
+            assert_equals(actual[i], expectation[i]);
+    }
+}
+
+test(function() {
+    var params = new URLSearchParams();
+    assert_equals(params + '', '');
+    params = new URLSearchParams('');
+    assert_equals(params + '', '');
+    params = new URLSearchParams('a=b');
+    assert_equals(params + '', 'a=b');
+    params = new URLSearchParams(params);
+    assert_equals(params + '', 'a=b');
+}, 'Basic URLSearchParams construction');
+
+test(function() {
+    assert_type_error(function () { URLSearchParams(); }, 'Failed to construct \'URLSearchParams\': Please use the \'new\' operator, this DOM object constructor cannot be called as a function.');
+
+    var params = new URLSearchParams('');
+    assert_not_equals(params, null, 'constructor returned non-null value.');
+    assert_equals(params.__proto__, URLSearchParams.prototype, 'expected URLSearchParams.prototype as prototype.');
+    params = new URLSearchParams({});
+    assert_equals(params + '', '%5Bobject+Object%5D=');
+}, 'URLSearchParams constructor, empty.');
+
+test(function() {
+    var params = new URLSearchParams('a=b');
+    assert_not_equals(params, null, 'constructor returned non-null value.');
+    assert_true(params.has('a'), 'Search params object has name "a"');
+    assert_false(params.has('b'), 'Search params object has not got name "b"');
+
+    var params = new URLSearchParams('a=b&c');
+    assert_not_equals(params, null, 'constructor returned non-null value.');
+    assert_true(params.has('a'), 'Search params object has name "a"');
+    assert_true(params.has('c'), 'Search params object has name "c"');
+
+    var params = new URLSearchParams('&a&&& &&&&&a+b=& c&m%c3%b8%c3%b8');
+    assert_not_equals(params, null, 'constructor returned non-null value.');
+    assert_true(params.has('a'), 'Search params object has name "a"');
+    assert_true(params.has('a b'), 'Search params object has name "a b"');
+    assert_true(params.has(' '), 'Search params object has name " "');
+    assert_false(params.has('c'), 'Search params object did not have the name "c"');
+    assert_true(params.has(' c'), 'Search params object has name " c"');
+    assert_true(params.has('møø'), 'Search params object has name "møø"');
+}, 'URLSearchParams constructor, string.');
+
+test(function() {
+    var seed = new URLSearchParams('a=b&c=d');
+    var params = new URLSearchParams(seed);
+    assert_not_equals(params, null, 'constructor returned non-null value.');
+    assert_iteration_equals(params, [ ['a', 'b' ], [ 'c', 'd' ] ]);
+    // The name-value pairs are copied when created; later updates
+    // should not be observable.
+    seed.append('e', 'f');
+    assert_false(params.has('e'));
+    params.append('g', 'h');
+    assert_false(seed.has('g'));
+}, 'URLSearchParams constructor, object.');
+
+test(function() {
+    var params = new URLSearchParams('a=b+c');
+    assert_equals(params.get('a'), 'b c');
+    params = new URLSearchParams('a+b=c');
+    assert_equals(params.get('a b'), 'c');
+}, 'Parse +');
+
+test(function() {
+    var params = new URLSearchParams('a=b%2Bc');
+    assert_equals(params.get('a'), 'b+c');
+    params = new URLSearchParams('a%2Bb=c');
+    assert_equals(params.get('a+b'), 'c');
+}, 'Parse %2B');
+
+test(function() {
+    var params = new URLSearchParams('a=b c');
+    assert_equals(params.get('a'), 'b c');
+    params = new URLSearchParams('a b=c');
+    assert_equals(params.get('a b'), 'c');
+}, 'Parse space');
+
+test(function() {
+    var params = new URLSearchParams('a=b%20c');
+    assert_equals(params.get('a'), 'b c');
+    params = new URLSearchParams('a%20b=c');
+    assert_equals(params.get('a b'), 'c');
+}, 'Parse %20');
+
+test(function() {
+    var params = new URLSearchParams('a=b\0c');
+    assert_equals(params.get('a'), 'b\0c');
+    params = new URLSearchParams('a\0b=c');
+    assert_equals(params.get('a\0b'), 'c');
+}, 'Parse \\0');
+
+test(function() {
+    var params = new URLSearchParams('a=b%00c');
+    assert_equals(params.get('a'), 'b\0c');
+    params = new URLSearchParams('a%00b=c');
+    assert_equals(params.get('a\0b'), 'c');
+}, 'Parse %00');
+
+test(function() {
+    var params = new URLSearchParams('a=b\u2384');
+    assert_equals(params.get('a'), 'b\u2384');
+    params = new URLSearchParams('a\u2384b=c');
+    assert_equals(params.get('a\u2384b'), 'c');
+}, 'Parse \u2384');  // Unicode Character 'COMPOSITION SYMBOL' (U+2384)
+
+test(function() {
+    var params = new URLSearchParams('a=b%e2%8e%84');
+    assert_equals(params.get('a'), 'b\u2384');
+    params = new URLSearchParams('a%e2%8e%84b=c');
+    assert_equals(params.get('a\u2384b'), 'c');
+}, 'Parse %e2%8e%84');  // Unicode Character 'COMPOSITION SYMBOL' (U+2384)
+
+test(function() {
+    var params = new URLSearchParams('a=b\uD83D\uDCA9c');
+    assert_equals(params.get('a'), 'b\uD83D\uDCA9c');
+    params = new URLSearchParams('a\uD83D\uDCA9b=c');
+    assert_equals(params.get('a\uD83D\uDCA9b'), 'c');
+}, 'Parse \uD83D\uDCA9');  // Unicode Character 'PILE OF POO' (U+1F4A9)
+
+test(function() {
+    var params = new URLSearchParams('a=b%f0%9f%92%a9c');
+    assert_equals(params.get('a'), 'b\uD83D\uDCA9c');
+    params = new URLSearchParams('a%f0%9f%92%a9b=c');
+    assert_equals(params.get('a\uD83D\uDCA9b'), 'c');
+}, 'Parse %f0%9f%92%a9');  // Unicode Character 'PILE OF POO' (U+1F4A9)
+
+test(function() {
+    var params = new URLSearchParams('=');
+    assert_equals(params.toString(), '=');
+}, 'Parse =');
+
+test(function() {
+    var params = new URLSearchParams('foobar=a\nb');
+    assert_equals(params.toString(), 'foobar=a%0Ab');
+}, 'Parse \\n');
+</script>
+</head>
+</html>
diff --git a/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-delete.html b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-delete.html
new file mode 100644
index 0000000..0ffae60
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-delete.html
@@ -0,0 +1,42 @@
+<!doctype html>
+<html>
+<head>
+<meta charset="utf8">
+<link rel="help" href="https://url.spec.whatwg.org/#dom-urlsearchparams-delete">
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script src="resources/testharness-extras.js"></script>
+<script>
+test(function() {
+    var params = new URLSearchParams('a=b&c=d');
+    params.delete('a');
+    assert_equals(params + '', 'c=d');
+    params = new URLSearchParams('a=a&b=b&a=a&c=c');
+    params.delete('a');
+    assert_equals(params + '', 'b=b&c=c');
+    params = new URLSearchParams('a=a&=&b=b&c=c');
+    params.delete('');
+    assert_equals(params + '', 'a=a&b=b&c=c');
+    params = new URLSearchParams('a=a&null=null&b=b');
+    params.delete(null);
+    assert_equals(params + '', 'a=a&b=b');
+    params = new URLSearchParams('a=a&undefined=undefined&b=b');
+    params.delete(undefined);
+    assert_equals(params + '', 'a=a&b=b');
+}, 'Delete basics');
+
+test(function() {
+    var params = new URLSearchParams();
+    params.append('first', 1);
+    assert_true(params.has('first'), 'Search params object has name "first"');
+    assert_equals(params.get('first'), '1', 'Search params object has name "first" with value "1"');
+    params.delete('first');
+    assert_false(params.has('first'), 'Search params object has no "first" name');
+    params.append('first', 1);
+    params.append('first', 10);
+    params.delete('first');
+    assert_false(params.has('first'), 'Search params object has no "first" name');
+}, 'Deleting appended multiple');
+</script>
+</head>
+</html>
diff --git a/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-get.html b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-get.html
new file mode 100644
index 0000000..91ef209a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-get.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<html>
+<head>
+<meta charset="utf8">
+<link rel="help" href="https://url.spec.whatwg.org/#dom-urlsearchparams-get">
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script src="resources/testharness-extras.js"></script>
+<script>
+test(function() {
+    var params = new URLSearchParams('a=b&c=d');
+    assert_equals(params.get('a'), 'b');
+    assert_equals(params.get('c'), 'd');
+    assert_equals(params.get('e'), null);
+    params = new URLSearchParams('a=b&c=d&a=e');
+    assert_equals(params.get('a'), 'b');
+    params = new URLSearchParams('=b&c=d');
+    assert_equals(params.get(''), 'b');
+    params = new URLSearchParams('a=&c=d&a=e');
+    assert_equals(params.get('a'), '');
+}, 'Get basics');
+
+test(function() {
+    var params = new URLSearchParams('first=second&third&&');
+    assert_true(params != null, 'constructor returned non-null value.');
+    assert_true(params.has('first'), 'Search params object has name "first"');
+    assert_equals(params.get('first'), 'second', 'Search params object has name "first" with value "second"');
+    assert_equals(params.get('third'), '', 'Search params object has name "third" with the empty value.');
+    assert_equals(params.get('fourth'), null, 'Search params object has no "fourth" name and value.');
+}, 'More get() basics');
+</script>
+</head>
+</html>
diff --git a/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-getall.html b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-getall.html
new file mode 100644
index 0000000..4454e2b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-getall.html
@@ -0,0 +1,37 @@
+<!doctype html>
+<html>
+<head>
+<meta charset="utf8">
+<link rel="help" href="https://url.spec.whatwg.org/#dom-urlsearchparams-getAll">
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script src="resources/testharness-extras.js"></script>
+<script>
+test(function() {
+    var params = new URLSearchParams('a=b&c=d');
+    assert_array_equals(params.getAll('a'), ['b']);
+    assert_array_equals(params.getAll('c'), ['d']);
+    assert_array_equals(params.getAll('e'), []);
+    params = new URLSearchParams('a=b&c=d&a=e');
+    assert_array_equals(params.getAll('a'), ['b', 'e']);
+    params = new URLSearchParams('=b&c=d');
+    assert_array_equals(params.getAll(''), ['b']);
+    params = new URLSearchParams('a=&c=d&a=e');
+    assert_array_equals(params.getAll('a'), ['', 'e']);
+}, 'getAll() basics');
+
+test(function() {
+    var params = new URLSearchParams('a=1&a=2&a=3&a');
+    assert_true(params.has('a'), 'Search params object has name "a"');
+    var matches = params.getAll('a');
+    assert_true(matches && matches.length == 4, 'Search params object has values for name "a"');
+    assert_array_equals(matches, ['1', '2', '3', ''], 'Search params object has expected name "a" values');
+    params.set('a', 'one');
+    assert_equals(params.get('a'), 'one', 'Search params object has name "a" with value "one"');
+    var matches = params.getAll('a');
+    assert_true(matches && matches.length == 1, 'Search params object has values for name "a"');
+    assert_array_equals(matches, ['one'], 'Search params object has expected name "a" values');
+}, 'getAll() multiples');
+</script>
+</head>
+</html>
diff --git a/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-has.html b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-has.html
new file mode 100644
index 0000000..e020253
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-has.html
@@ -0,0 +1,36 @@
+<!doctype html>
+<html>
+<head>
+<meta charset="utf8">
+<link rel="help" href="https://url.spec.whatwg.org/#dom-urlsearchparams-has">
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script src="resources/testharness-extras.js"></script>
+<script>
+test(function() {
+    var params = new URLSearchParams('a=b&c=d');
+    assert_true(params.has('a'));
+    assert_true(params.has('c'));
+    assert_false(params.has('e'));
+    params = new URLSearchParams('a=b&c=d&a=e');
+    assert_true(params.has('a'));
+    params = new URLSearchParams('=b&c=d');
+    assert_true(params.has(''));
+    params = new URLSearchParams('null=a');
+    assert_true(params.has(null));
+}, 'has() basics');
+
+test(function() {
+    var params = new URLSearchParams('a=b&c=d&&');
+    params.append('first', 1);
+    params.append('first', 2);
+    assert_true(params.has('a'), 'Search params object has name "a"');
+    assert_true(params.has('c'), 'Search params object has name "c"');
+    assert_true(params.has('first'), 'Search params object has name "first"');
+    assert_false(params.has('d'), 'Search params object has no name "d"');
+    params.delete('first');
+    assert_false(params.has('first'), 'Search params object has no name "first"');
+}, 'has() following delete()');
+</script>
+</head>
+</html>
diff --git a/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-iterable.html b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-iterable.html
new file mode 100644
index 0000000..3e7b0f0
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-iterable.html
@@ -0,0 +1,66 @@
+<!doctype html>
+<html>
+<head>
+<meta charset="utf8">
+<link rel="help" href="https://url.spec.whatwg.org/#dom-urlsearchparams">
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script>
+var expectedValues = {
+    'a': '1',
+    'b': '2',
+    'c': '3'
+};
+
+var params = new URLSearchParams();
+params.append('a', '1');
+params.append('b', '2');
+params.append('c', '3');
+
+test(function() {
+    for (var param of params) {
+        var key = param[0];
+        var value = param[1];
+        assert_true(key in expectedValues);
+        assert_equals(params.get(key), expectedValues[key]);
+        assert_equals(value, expectedValues[key]);
+    }
+}, 'for...of Iteration');
+
+test(function() {
+    for (var key of params.keys()) {
+        assert_true(key in expectedValues);
+        assert_equals(params.get(key), expectedValues[key]);
+    }
+}, 'keys');
+
+test(function() {
+    var expectedKeys = {};
+    for (var key in expectedValues)
+        expectedKeys[expectedValues[key]] = key;
+
+    for (var value of params.values())
+        assert_true(value in expectedKeys);
+}, 'values');
+
+test(function () {
+    for (var param of params.entries()) {
+        var key = param[0];
+        var value = param[1];
+        assert_true(key in expectedValues);
+        assert_equals(params.get(key), expectedValues[key]);
+        assert_equals(value, expectedValues[key]);
+    }
+}, 'entries');
+
+test(function () {
+    params.forEach(function (value, key, paramsObject) {
+        assert_true(key in expectedValues);
+        assert_equals(params.get(key), expectedValues[key]);
+        assert_equals(value, expectedValues[key]);
+        assert_equals(paramsObject, params);
+    });
+}, 'forEach');
+</script>
+</head>
+</html>
diff --git a/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-set.html b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-set.html
new file mode 100644
index 0000000..bb9b8a1
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-set.html
@@ -0,0 +1,37 @@
+<!doctype html>
+<html>
+<head>
+<meta charset="utf8">
+<link rel="help" href="https://url.spec.whatwg.org/#dom-urlsearchparams-set">
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script src="resources/testharness-extras.js"></script>
+<script>
+test(function() {
+    var params = new URLSearchParams('a=b&c=d');
+    params.set('a', 'B');
+    assert_equals(params + '', 'a=B&c=d');
+    params = new URLSearchParams('a=b&c=d&a=e');
+    params.set('a', 'B');
+    assert_equals(params + '', 'a=B&c=d')
+    params.set('e', 'f');
+    assert_equals(params + '', 'a=B&c=d&e=f')
+}, 'set() basics');
+
+test(function() {
+    var params = new URLSearchParams('a=1&a=2&a=3');
+    assert_true(params.has('a'), 'Search params object has name "a"');
+    assert_equals(params.get('a'), '1', 'Search params object has name "a" with value "1"');
+    params.set('first', 4);
+    assert_true(params.has('a'), 'Search params object has name "a"');
+    assert_equals(params.get('a'), '1', 'Search params object has name "a" with value "1"');
+    assert_equals(params + '', 'a=1&a=2&a=3&first=4');
+    params.set('a', 4);
+    assert_true(params.has('a'), 'Search params object has name "a"');
+    assert_equals(params.get('a'), '4', 'Search params object has name "a" with value "4"');
+    assert_equals(params + '', 'a=4&first=4');
+}, 'set() replaces multiple values');
+</script>
+</head>
+</html>
+
diff --git a/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-stringifier-expected.txt b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-stringifier-expected.txt
new file mode 100644
index 0000000..397c97b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-stringifier-expected.txt
@@ -0,0 +1,270 @@
+This is a testharness.js-based test.
+PASS Serialize space 
+PASS Serialize empty value 
+PASS Serialize empty name 
+PASS Serialize empty name and value 
+PASS Serialize + 
+PASS Serialize = 
+PASS Serialize & 
+PASS Serialize U+0000 -> '\0' 
+PASS Serialize U+0001 -> '' 
+PASS Serialize U+0002 -> '' 
+PASS Serialize U+0003 -> '' 
+PASS Serialize U+0004 -> '' 
+PASS Serialize U+0005 -> '' 
+PASS Serialize U+0006 -> '' 
+PASS Serialize U+0007 -> '' 
+PASS Serialize U+0008 -> '' 
+PASS Serialize U+0009 -> '	' 
+PASS Serialize U+000A -> '
+' 
+PASS Serialize U+000B -> '' 
+PASS Serialize U+000C -> '' 
+PASS Serialize U+000D -> '\r' 
+PASS Serialize U+000E -> '' 
+PASS Serialize U+000F -> '' 
+PASS Serialize U+0010 -> '' 
+PASS Serialize U+0011 -> '' 
+PASS Serialize U+0012 -> '' 
+PASS Serialize U+0013 -> '' 
+PASS Serialize U+0014 -> '' 
+PASS Serialize U+0015 -> '' 
+PASS Serialize U+0016 -> '' 
+PASS Serialize U+0017 -> '' 
+PASS Serialize U+0018 -> '' 
+PASS Serialize U+0019 -> '' 
+PASS Serialize U+001A -> '' 
+PASS Serialize U+001B -> '' 
+PASS Serialize U+001C -> '' 
+PASS Serialize U+001D -> '' 
+PASS Serialize U+001E -> '' 
+PASS Serialize U+001F -> '' 
+PASS Serialize U+0020 -> ' ' 
+FAIL Serialize U+0021 -> '!' assert_equals: expected "33=%21" but got "33=!"
+PASS Serialize U+0022 -> '"' 
+PASS Serialize U+0023 -> '#' 
+PASS Serialize U+0024 -> '$' 
+PASS Serialize U+0025 -> '%' 
+PASS Serialize U+0026 -> '&' 
+PASS Serialize U+0027 -> ''' 
+FAIL Serialize U+0028 -> '(' assert_equals: expected "40=%28" but got "40=("
+FAIL Serialize U+0029 -> ')' assert_equals: expected "41=%29" but got "41=)"
+PASS Serialize U+002A -> '*' 
+PASS Serialize U+002B -> '+' 
+PASS Serialize U+002C -> ',' 
+PASS Serialize U+002D -> '-' 
+PASS Serialize U+002E -> '.' 
+FAIL Serialize U+002F -> '/' assert_equals: expected "47=%2F" but got "47=/"
+PASS Serialize U+0030 -> '0' 
+PASS Serialize U+0031 -> '1' 
+PASS Serialize U+0032 -> '2' 
+PASS Serialize U+0033 -> '3' 
+PASS Serialize U+0034 -> '4' 
+PASS Serialize U+0035 -> '5' 
+PASS Serialize U+0036 -> '6' 
+PASS Serialize U+0037 -> '7' 
+PASS Serialize U+0038 -> '8' 
+PASS Serialize U+0039 -> '9' 
+PASS Serialize U+003A -> ':' 
+PASS Serialize U+003B -> ';' 
+PASS Serialize U+003C -> '<' 
+PASS Serialize U+003D -> '=' 
+PASS Serialize U+003E -> '>' 
+PASS Serialize U+003F -> '?' 
+PASS Serialize U+0040 -> '@' 
+PASS Serialize U+0041 -> 'A' 
+PASS Serialize U+0042 -> 'B' 
+PASS Serialize U+0043 -> 'C' 
+PASS Serialize U+0044 -> 'D' 
+PASS Serialize U+0045 -> 'E' 
+PASS Serialize U+0046 -> 'F' 
+PASS Serialize U+0047 -> 'G' 
+PASS Serialize U+0048 -> 'H' 
+PASS Serialize U+0049 -> 'I' 
+PASS Serialize U+004A -> 'J' 
+PASS Serialize U+004B -> 'K' 
+PASS Serialize U+004C -> 'L' 
+PASS Serialize U+004D -> 'M' 
+PASS Serialize U+004E -> 'N' 
+PASS Serialize U+004F -> 'O' 
+PASS Serialize U+0050 -> 'P' 
+PASS Serialize U+0051 -> 'Q' 
+PASS Serialize U+0052 -> 'R' 
+PASS Serialize U+0053 -> 'S' 
+PASS Serialize U+0054 -> 'T' 
+PASS Serialize U+0055 -> 'U' 
+PASS Serialize U+0056 -> 'V' 
+PASS Serialize U+0057 -> 'W' 
+PASS Serialize U+0058 -> 'X' 
+PASS Serialize U+0059 -> 'Y' 
+PASS Serialize U+005A -> 'Z' 
+PASS Serialize U+005B -> '[' 
+PASS Serialize U+005C -> '\' 
+PASS Serialize U+005D -> ']' 
+PASS Serialize U+005E -> '^' 
+PASS Serialize U+005F -> '_' 
+PASS Serialize U+0060 -> '`' 
+PASS Serialize U+0061 -> 'a' 
+PASS Serialize U+0062 -> 'b' 
+PASS Serialize U+0063 -> 'c' 
+PASS Serialize U+0064 -> 'd' 
+PASS Serialize U+0065 -> 'e' 
+PASS Serialize U+0066 -> 'f' 
+PASS Serialize U+0067 -> 'g' 
+PASS Serialize U+0068 -> 'h' 
+PASS Serialize U+0069 -> 'i' 
+PASS Serialize U+006A -> 'j' 
+PASS Serialize U+006B -> 'k' 
+PASS Serialize U+006C -> 'l' 
+PASS Serialize U+006D -> 'm' 
+PASS Serialize U+006E -> 'n' 
+PASS Serialize U+006F -> 'o' 
+PASS Serialize U+0070 -> 'p' 
+PASS Serialize U+0071 -> 'q' 
+PASS Serialize U+0072 -> 'r' 
+PASS Serialize U+0073 -> 's' 
+PASS Serialize U+0074 -> 't' 
+PASS Serialize U+0075 -> 'u' 
+PASS Serialize U+0076 -> 'v' 
+PASS Serialize U+0077 -> 'w' 
+PASS Serialize U+0078 -> 'x' 
+PASS Serialize U+0079 -> 'y' 
+PASS Serialize U+007A -> 'z' 
+PASS Serialize U+007B -> '{' 
+PASS Serialize U+007C -> '|' 
+PASS Serialize U+007D -> '}' 
+FAIL Serialize U+007E -> '~' assert_equals: expected "126=%7E" but got "126=~"
+PASS Serialize U+007F -> '' 
+PASS Serialize U+0080 -> '€' 
+PASS Serialize U+0081 -> '' 
+PASS Serialize U+0082 -> '‚' 
+PASS Serialize U+0083 -> 'ƒ' 
+PASS Serialize U+0084 -> '„' 
+PASS Serialize U+0085 -> '…' 
+PASS Serialize U+0086 -> '†' 
+PASS Serialize U+0087 -> '‡' 
+PASS Serialize U+0088 -> 'ˆ' 
+PASS Serialize U+0089 -> '‰' 
+PASS Serialize U+008A -> 'Š' 
+PASS Serialize U+008B -> '‹' 
+PASS Serialize U+008C -> 'Œ' 
+PASS Serialize U+008D -> '' 
+PASS Serialize U+008E -> 'Ž' 
+PASS Serialize U+008F -> '' 
+PASS Serialize U+0090 -> '' 
+PASS Serialize U+0091 -> '‘' 
+PASS Serialize U+0092 -> '’' 
+PASS Serialize U+0093 -> '“' 
+PASS Serialize U+0094 -> '”' 
+PASS Serialize U+0095 -> '•' 
+PASS Serialize U+0096 -> '–' 
+PASS Serialize U+0097 -> '—' 
+PASS Serialize U+0098 -> '˜' 
+PASS Serialize U+0099 -> '™' 
+PASS Serialize U+009A -> 'š' 
+PASS Serialize U+009B -> '›' 
+PASS Serialize U+009C -> 'œ' 
+PASS Serialize U+009D -> '' 
+PASS Serialize U+009E -> 'ž' 
+PASS Serialize U+009F -> 'Ÿ' 
+PASS Serialize U+00A0 -> ' ' 
+PASS Serialize U+00A1 -> '¡' 
+PASS Serialize U+00A2 -> '¢' 
+PASS Serialize U+00A3 -> '£' 
+PASS Serialize U+00A4 -> '¤' 
+PASS Serialize U+00A5 -> '¥' 
+PASS Serialize U+00A6 -> '¦' 
+PASS Serialize U+00A7 -> '§' 
+PASS Serialize U+00A8 -> '¨' 
+PASS Serialize U+00A9 -> '©' 
+PASS Serialize U+00AA -> 'ª' 
+PASS Serialize U+00AB -> '«' 
+PASS Serialize U+00AC -> '¬' 
+PASS Serialize U+00AD -> '­' 
+PASS Serialize U+00AE -> '®' 
+PASS Serialize U+00AF -> '¯' 
+PASS Serialize U+00B0 -> '°' 
+PASS Serialize U+00B1 -> '±' 
+PASS Serialize U+00B2 -> '²' 
+PASS Serialize U+00B3 -> '³' 
+PASS Serialize U+00B4 -> '´' 
+PASS Serialize U+00B5 -> 'µ' 
+PASS Serialize U+00B6 -> '¶' 
+PASS Serialize U+00B7 -> '·' 
+PASS Serialize U+00B8 -> '¸' 
+PASS Serialize U+00B9 -> '¹' 
+PASS Serialize U+00BA -> 'º' 
+PASS Serialize U+00BB -> '»' 
+PASS Serialize U+00BC -> '¼' 
+PASS Serialize U+00BD -> '½' 
+PASS Serialize U+00BE -> '¾' 
+PASS Serialize U+00BF -> '¿' 
+PASS Serialize U+00C0 -> 'À' 
+PASS Serialize U+00C1 -> 'Á' 
+PASS Serialize U+00C2 -> 'Â' 
+PASS Serialize U+00C3 -> 'Ã' 
+PASS Serialize U+00C4 -> 'Ä' 
+PASS Serialize U+00C5 -> 'Å' 
+PASS Serialize U+00C6 -> 'Æ' 
+PASS Serialize U+00C7 -> 'Ç' 
+PASS Serialize U+00C8 -> 'È' 
+PASS Serialize U+00C9 -> 'É' 
+PASS Serialize U+00CA -> 'Ê' 
+PASS Serialize U+00CB -> 'Ë' 
+PASS Serialize U+00CC -> 'Ì' 
+PASS Serialize U+00CD -> 'Í' 
+PASS Serialize U+00CE -> 'Î' 
+PASS Serialize U+00CF -> 'Ï' 
+PASS Serialize U+00D0 -> 'Ð' 
+PASS Serialize U+00D1 -> 'Ñ' 
+PASS Serialize U+00D2 -> 'Ò' 
+PASS Serialize U+00D3 -> 'Ó' 
+PASS Serialize U+00D4 -> 'Ô' 
+PASS Serialize U+00D5 -> 'Õ' 
+PASS Serialize U+00D6 -> 'Ö' 
+PASS Serialize U+00D7 -> '×' 
+PASS Serialize U+00D8 -> 'Ø' 
+PASS Serialize U+00D9 -> 'Ù' 
+PASS Serialize U+00DA -> 'Ú' 
+PASS Serialize U+00DB -> 'Û' 
+PASS Serialize U+00DC -> 'Ü' 
+PASS Serialize U+00DD -> 'Ý' 
+PASS Serialize U+00DE -> 'Þ' 
+PASS Serialize U+00DF -> 'ß' 
+PASS Serialize U+00E0 -> 'à' 
+PASS Serialize U+00E1 -> 'á' 
+PASS Serialize U+00E2 -> 'â' 
+PASS Serialize U+00E3 -> 'ã' 
+PASS Serialize U+00E4 -> 'ä' 
+PASS Serialize U+00E5 -> 'å' 
+PASS Serialize U+00E6 -> 'æ' 
+PASS Serialize U+00E7 -> 'ç' 
+PASS Serialize U+00E8 -> 'è' 
+PASS Serialize U+00E9 -> 'é' 
+PASS Serialize U+00EA -> 'ê' 
+PASS Serialize U+00EB -> 'ë' 
+PASS Serialize U+00EC -> 'ì' 
+PASS Serialize U+00ED -> 'í' 
+PASS Serialize U+00EE -> 'î' 
+PASS Serialize U+00EF -> 'ï' 
+PASS Serialize U+00F0 -> 'ð' 
+PASS Serialize U+00F1 -> 'ñ' 
+PASS Serialize U+00F2 -> 'ò' 
+PASS Serialize U+00F3 -> 'ó' 
+PASS Serialize U+00F4 -> 'ô' 
+PASS Serialize U+00F5 -> 'õ' 
+PASS Serialize U+00F6 -> 'ö' 
+PASS Serialize U+00F7 -> '÷' 
+PASS Serialize U+00F8 -> 'ø' 
+PASS Serialize U+00F9 -> 'ù' 
+PASS Serialize U+00FA -> 'ú' 
+PASS Serialize U+00FB -> 'û' 
+PASS Serialize U+00FC -> 'ü' 
+PASS Serialize U+00FD -> 'ý' 
+PASS Serialize U+00FE -> 'þ' 
+PASS Serialize % 
+PASS Serialize \0 
+PASS Serialize 💩 
+PASS URLSearchParams.toString 
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-stringifier.html b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-stringifier.html
new file mode 100644
index 0000000..495a1ac3
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-stringifier.html
@@ -0,0 +1,146 @@
+<!doctype html>
+<html>
+<head>
+<meta charset="utf8">
+<link rel="help" href="https://url.spec.whatwg.org/#dom-urlsearchparams-set">
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script src="resources/testharness-extras.js"></script>
+<script>
+test(function() {
+    var params = new URLSearchParams();
+    params.append('a', 'b c');
+    assert_equals(params + '', 'a=b+c');
+    params.delete('a');
+    params.append('a b', 'c');
+    assert_equals(params + '', 'a+b=c');
+}, 'Serialize space');
+
+test(function() {
+    var params = new URLSearchParams();
+    params.append('a', '');
+    assert_equals(params + '', 'a=');
+    params.append('a', '');
+    assert_equals(params + '', 'a=&a=');
+    params.append('', 'b');
+    assert_equals(params + '', 'a=&a=&=b');
+    params.append('', '');
+    assert_equals(params + '', 'a=&a=&=b&=');
+    params.append('', '');
+    assert_equals(params + '', 'a=&a=&=b&=&=');
+}, 'Serialize empty value');
+
+test(function() {
+    var params = new URLSearchParams();
+    params.append('', 'b');
+    assert_equals(params + '', '=b');
+    params.append('', 'b');
+    assert_equals(params + '', '=b&=b');
+}, 'Serialize empty name');
+
+test(function() {
+    var params = new URLSearchParams();
+    params.append('', '');
+    assert_equals(params + '', '=');
+    params.append('', '');
+    assert_equals(params + '', '=&=');
+}, 'Serialize empty name and value');
+
+test(function() {
+    var params = new URLSearchParams();
+    params.append('a', 'b+c');
+    assert_equals(params + '', 'a=b%2Bc');
+    params.delete('a');
+    params.append('a+b', 'c');
+    assert_equals(params + '', 'a%2Bb=c');
+}, 'Serialize +');
+
+test(function() {
+    var params = new URLSearchParams();
+    params.append('=', 'a');
+    assert_equals(params + '', '%3D=a');
+    params.append('b', '=');
+    assert_equals(params + '', '%3D=a&b=%3D');
+}, 'Serialize =');
+
+test(function() {
+    var params = new URLSearchParams();
+    params.append('&', 'a');
+    assert_equals(params + '', '%26=a');
+    params.append('b', '&');
+    assert_equals(params + '', '%26=a&b=%26');
+}, 'Serialize &');
+
+function intToHex(i) {
+    return (i<0x10 ? '0':'') + i.toString(16).toUpperCase();
+}
+
+function urlEncodedSerialize(n) {
+  if (n === 0x20) {
+    return "\x2B";
+  }
+
+  if (n === 0x2A || n === 0x2D || n === 0x2E ||
+      (0x30 <= n && n <= 0x39) || (0x41 <= n && n <= 0x5A) ||
+      n === 0x5F || (0x61 <= n && n <= 0x7A)) {
+    return String.fromCharCode(n);
+  }
+  var bytes = (new TextEncoder()).encode(String.fromCharCode(n));
+  var ret = "";
+  for (var i = 0; i < bytes.length; i++) {
+      ret += "%" + intToHex(bytes[i]);
+  }
+  return ret;
+}
+
+for (var i = 0x00; i < 0xFF; i++) {
+    // Not all bytes can appear in valid UTF-8, so some bytes aren't covered.
+    // TODO(mkwst): We fail to properly encode a few bytes: https://crbug.com/557063
+    test(function() {
+        var params = new URLSearchParams();
+        params.append('' + i, String.fromCodePoint(i));
+        assert_equals(params + '', '' + i + '=' + urlEncodedSerialize(i));
+    }, "Serialize U+00" + intToHex(i) + " -> '" + String.fromCodePoint(i) + "'");
+}
+
+test(function() {
+    var params = new URLSearchParams();
+    params.append('a', 'b%c');
+    assert_equals(params + '', 'a=b%25c');
+    params.delete('a');
+    params.append('a%b', 'c');
+    assert_equals(params + '', 'a%25b=c');
+}, 'Serialize %');
+
+test(function() {
+    var params = new URLSearchParams();
+    params.append('a', 'b\0c');
+    assert_equals(params + '', 'a=b%00c');
+    params.delete('a');
+    params.append('a\0b', 'c');
+    assert_equals(params + '', 'a%00b=c');
+}, 'Serialize \\0');
+
+test(function() {
+    var params = new URLSearchParams();
+    params.append('a', 'b\uD83D\uDCA9c');
+    assert_equals(params + '', 'a=b%F0%9F%92%A9c');
+    params.delete('a');
+    params.append('a\uD83D\uDCA9b', 'c');
+    assert_equals(params + '', 'a%F0%9F%92%A9b=c');
+}, 'Serialize \uD83D\uDCA9');  // Unicode Character 'PILE OF POO' (U+1F4A9)
+
+test(function() {
+    var params;
+    params = new URLSearchParams('a=b&c=d&&e&&');
+    assert_equals(params.toString(), 'a=b&c=d&e=');
+    params = new URLSearchParams('a = b &a=b&c=d%20');
+    assert_equals(params.toString(), 'a+=+b+&a=b&c=d+');
+    // The lone '=' _does_ survive the roundtrip.
+    params = new URLSearchParams('a=&a=b');
+    assert_equals(params.toString(), 'a=&a=b');
+}, 'URLSearchParams.toString');
+</script>
+</head>
+</html>
+
diff --git a/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-worker.html b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-worker.html
new file mode 100644
index 0000000..5fb8474
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-worker.html
@@ -0,0 +1,12 @@
+<!doctype html>
+<html>
+<head>
+<meta charset="utf8">
+<link rel="help" href="https://url.spec.whatwg.org/#interface-urlsearchparams">
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script>
+fetch_tests_from_worker(new Worker("./resources/urlsearchparams-worker.js"));
+</script>
+</head>
+</html>
diff --git a/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams.html b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams.html
new file mode 100644
index 0000000..80861f51
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<html>
+<head>
+<meta charset="utf8">
+<link rel="help" href="https://url.spec.whatwg.org/#interface-urlsearchparams">
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script>
+test(function() {
+    assert_true('URLSearchParams' in window);
+    assert_true('toString' in URLSearchParams.prototype);
+    assert_true('append' in URLSearchParams.prototype);
+    assert_true('delete' in URLSearchParams.prototype);
+    assert_true('get' in URLSearchParams.prototype);
+    assert_true('getAll' in URLSearchParams.prototype);
+    assert_true('has' in URLSearchParams.prototype);
+    assert_true('set' in URLSearchParams.prototype);
+}, 'URLSearchParams interface');
+</script>
+</head>
+</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/background_sync/interfaces.html b/third_party/WebKit/LayoutTests/http/tests/background_sync/interfaces.html
index c5d4e1b2..d183f40 100644
--- a/third_party/WebKit/LayoutTests/http/tests/background_sync/interfaces.html
+++ b/third_party/WebKit/LayoutTests/http/tests/background_sync/interfaces.html
@@ -18,23 +18,9 @@
           assert_own_property(self, 'SyncManager', 'SyncManager needs to be exposed as a global.');
 
           assert_own_property(SyncManager.prototype, 'register');
-          assert_own_property(SyncManager.prototype, 'getRegistration');
-          assert_own_property(SyncManager.prototype, 'getRegistrations');
-          assert_own_property(SyncManager.prototype, 'permissionState');
+          assert_own_property(SyncManager.prototype, 'getTags');
 
       }, 'SyncManager should be exposed and have the expected interface in a Document.');
-
-      test(function() {
-          assert_own_property(self, 'SyncRegistration', 'SyncRegistration needs to be exposed as a global.');
-
-          // FIXME: Assert existence of the attributes when they are properly
-          // exposed in the prototype chain. https://crbug.com/43394
-
-          assert_own_property(SyncRegistration.prototype, 'finished');
-          assert_own_property(SyncRegistration.prototype, 'unregister');
-          assert_own_property(SyncRegistration.prototype, 'tag');
-
-      }, 'SyncRegistration should be exposed and have the expected interface in a Document.');
     </script>
   </body>
 </html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/background_sync/oneshot-register-failure-worker-not-activated.html b/third_party/WebKit/LayoutTests/http/tests/background_sync/oneshot-register-failure-worker-not-activated.html
index 7768008..9b35a5e 100644
--- a/third_party/WebKit/LayoutTests/http/tests/background_sync/oneshot-register-failure-worker-not-activated.html
+++ b/third_party/WebKit/LayoutTests/http/tests/background_sync/oneshot-register-failure-worker-not-activated.html
@@ -17,7 +17,7 @@
             swRegistration = serviceWorkerRegistration;
             assert_not_equals(swRegistration.installing, null, 'The worker should be installing');
             assert_equals(swRegistration.active, null, 'The worker should not be active yet');
-            return swRegistration.sync.register();
+            return swRegistration.sync.register('abcde');
         })
         .then(function(syncRegistration) {
             assert_unreached('sync.register() must not succeed without an active service worker');
diff --git a/third_party/WebKit/LayoutTests/http/tests/background_sync/oneshot.html b/third_party/WebKit/LayoutTests/http/tests/background_sync/oneshot.html
index 87663fa6..e2090b94 100644
--- a/third_party/WebKit/LayoutTests/http/tests/background_sync/oneshot.html
+++ b/third_party/WebKit/LayoutTests/http/tests/background_sync/oneshot.html
@@ -6,7 +6,6 @@
 <script src="../resources/testharness-helpers.js"></script>
 <script src="../resources/testharnessreport.js"></script>
 <script src="../serviceworker/resources/test-helpers.js"></script>
-<script src="resources/test-helpers.js"></script>
 <script>
 
 promise_test(function(t) {
@@ -15,9 +14,9 @@
   var sync_manager;
   var sync_registration;
 
-  // One-shot syncs can only be registered from a controlled document. This
-  // test creates a frame, after the service worker is active, in order to use
-  // its service worker registration.
+  // This test verifies that one-shot syncs can be registered from service-
+  // worker-controlled documents. It creates a frame, after the service worker
+  // is active, in order to use its service worker registration.
   return service_worker_unregister_and_register(t, url, scope)
     .then(function(sw_registration_page) {
         return wait_for_state(t, sw_registration_page.installing, 'activated');
@@ -31,21 +30,14 @@
       })
     .then(function(sw_registration_frame) {
         sync_manager = sw_registration_frame.sync;
-        return clear_registered_syncs(sync_manager);
+        return sync_manager.getTags();
       })
-    .then(function() { return sync_manager.getRegistrations(); })
-    .then(function(registrations) {
-        assert_equals(registrations.length, 0, 'One-shot syncs should be ' +
+    .then(function(tags) {
+        assert_equals(tags.length, 0, 'One-shot syncs should be ' +
                       'cleared at the start of the test.');
-        return sync_manager.register({tag: 'abcde'});
+        return sync_manager.register('abcde');
       })
-    .then(function(registration) {
-        sync_registration = registration;
-        assert_class_string(sync_registration, 'SyncRegistration', 'One-' +
-                            'shot sync registrations should have the correct ' +
-                            'class name.');
-        assert_equals('abcde', registration.tag, 'Sync registration tag ' +
-                      'returned should match the tag registered.');
+    .then(function() {
         return service_worker_unregister(t, scope);
       });
   }, 'Background Sync API should allow one-shot syncs to be registered from ' +
@@ -57,31 +49,22 @@
   var sync_manager;
   var sync_registration;
 
-  // One-shot syncs can also be registered from uncontrolled documents. This
-  // test creates a frame, after the service worker is active, in order to use
-  // its service worker registration.
+  // This test verifies that one-shot syncs can be registered from uncontrolled
+  // documents.
   return service_worker_unregister_and_register(t, url, scope)
     .then(function(sw_registration) {
         sync_manager = sw_registration.sync;
         return wait_for_state(t, sw_registration.installing, 'activated');
       })
-    .then(function() { return clear_registered_syncs(sync_manager); })
-    .then(function() { return sync_manager.getRegistrations(); })
-    .then(function(registrations) {
-        assert_equals(registrations.length, 0, 'One-shot syncs should be ' +
+    .then(function() { return sync_manager.getTags(); })
+    .then(function(tags) {
+        assert_equals(tags.length, 0, 'One-shot syncs should be ' +
                       'cleared at the start of the test.');
-        return sync_manager.register({tag: 'abcde'});
+        return sync_manager.register('abcde');
       })
-    .then(function(registration) {
-        sync_registration = registration;
-        assert_class_string(sync_registration, 'SyncRegistration', 'One-' +
-                            'shot sync registrations should have the correct ' +
-                            'class name.');
-        assert_equals('abcde', registration.tag, 'Sync registration tag ' +
-                      'returned should match the tag registered.');
+    .then(function() {
         return service_worker_unregister(t, scope);
       })
-    .then(function() { return service_worker_unregister(t, scope); })
   }, 'Background Sync API should allow one-shot syncs to be registered ' +
      'with window clients not currently controlled by service worker');
 </script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/background_sync/resources/interfaces-worker.js b/third_party/WebKit/LayoutTests/http/tests/background_sync/resources/interfaces-worker.js
index c638025c..0df2dca6 100644
--- a/third_party/WebKit/LayoutTests/http/tests/background_sync/resources/interfaces-worker.js
+++ b/third_party/WebKit/LayoutTests/http/tests/background_sync/resources/interfaces-worker.js
@@ -6,27 +6,14 @@
     assert_idl_attribute(registration, 'sync', 'One-shot SyncManager needs to be exposed on the registration.');
 
     assert_inherits(registration.sync, 'register');
-    assert_inherits(registration.sync, 'getRegistration');
-    assert_inherits(registration.sync, 'getRegistrations');
-    assert_inherits(registration.sync, 'permissionState');
+    assert_inherits(registration.sync, 'getTags');
 
 }, 'SyncManager should be exposed and have the expected interface.');
 
 test(function() {
-    assert_own_property(self, 'SyncRegistration', 'SyncRegistration needs to be exposed as a global.');
-
-    // FIXME: Assert existence of the attributes when they are properly
-    // exposed in the prototype chain. https://crbug.com/43394
-    assert_own_property(SyncRegistration.prototype, 'finished');
-    assert_own_property(SyncRegistration.prototype, 'unregister');
-    assert_own_property(SyncRegistration.prototype, 'tag');
-
-}, 'SyncRegistration should be exposed and have the expected interface.');
-
-test(function() {
     assert_own_property(self, 'SyncEvent');
 
-    assert_will_be_idl_attribute(SyncEvent.prototype, 'registration');
+    assert_will_be_idl_attribute(SyncEvent.prototype, 'tag');
 
     // SyncEvent should be extending ExtendableEvent.
     assert_inherits(SyncEvent.prototype, 'waitUntil');
diff --git a/third_party/WebKit/LayoutTests/http/tests/background_sync/resources/test-helpers.js b/third_party/WebKit/LayoutTests/http/tests/background_sync/resources/test-helpers.js
deleted file mode 100644
index da0b7e9..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/background_sync/resources/test-helpers.js
+++ /dev/null
@@ -1,13 +0,0 @@
-// Returns a promise which resolves when all registrations have been cleared
-// from the given background sync manager.
-function clear_registered_syncs(sync_manager) {
-  return sync_manager.getRegistrations().then(function(registrations) {
-    return Promise.all(
-      registrations.map(registration => registration.unregister()));
-  });
-}
-
-// Clears all background sync registrations from the sync manager.
-function clear_all_syncs(serviceworker_registration) {
-  return clear_registered_syncs(serviceworker_registration.sync);
-}
diff --git a/third_party/WebKit/LayoutTests/http/tests/misc/script-sync-slow-scripts-onerror-expected.txt b/third_party/WebKit/LayoutTests/http/tests/misc/script-sync-slow-scripts-onerror-expected.txt
index 12463f9..4328e54 100644
--- a/third_party/WebKit/LayoutTests/http/tests/misc/script-sync-slow-scripts-onerror-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/misc/script-sync-slow-scripts-onerror-expected.txt
@@ -3,9 +3,8 @@
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-PASS firstOnErrorHandlerHasRun is false
-PASS firstOnErrorHandlerHasRun is true
-PASS secondOnErrorHandlerHasRun is false
+PASS firstOnErrorHandlerCount is 1
+PASS secondOnErrorHandlerCount is 1
 PASS successfullyParsed is true
 
 TEST COMPLETE
diff --git a/third_party/WebKit/LayoutTests/http/tests/misc/script-sync-slow-scripts-onerror.html b/third_party/WebKit/LayoutTests/http/tests/misc/script-sync-slow-scripts-onerror.html
index 31138b6..e21084597 100644
--- a/third_party/WebKit/LayoutTests/http/tests/misc/script-sync-slow-scripts-onerror.html
+++ b/third_party/WebKit/LayoutTests/http/tests/misc/script-sync-slow-scripts-onerror.html
@@ -25,22 +25,27 @@
     testRunner.waitUntilDone();
 }
 
-var firstOnErrorHandlerHasRun = false;
+var firstOnErrorHandlerCount = 0;
+var secondOnErrorHandlerCount = 0;
+function verifyAndFinish() {
+    shouldBe("firstOnErrorHandlerCount", "1");
+    shouldBe("secondOnErrorHandlerCount", "1");
+    finishJSTest();
+};
+
 function failedFirst() {
-    shouldBeFalse("firstOnErrorHandlerHasRun");
-    firstOnErrorHandlerHasRun = true;
+    firstOnErrorHandlerCount++;
     // Issue another script load so as to have the script runner
     // revisit its script queue. This should not result in this
     // onerror handler running again.
-    loadScript("resources/success.js?1", true);
+    var continuation = secondOnErrorHandlerCount ? verifyAndFinish : undefined;
+    loadScript("resources/success.js?1", true, continuation);
 }
 
-var secondOnErrorHandlerHasRun = false;
 function failedSecond() {
-    shouldBeTrue("firstOnErrorHandlerHasRun");
-    shouldBeFalse("secondOnErrorHandlerHasRun");
-    secondOnErrorHandlerHasRun = true;
-    loadScript("resources/success.js?2", true, finishJSTest);
+    secondOnErrorHandlerCount++;
+    var continuation = firstOnErrorHandlerCount ? verifyAndFinish : undefined;
+    loadScript("resources/success.js?2", true, continuation);
 }
 
 function unexpectedLoad() {
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 bf66956..54605ce 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
@@ -587,19 +587,12 @@
     method wrapKey
 interface SyncEvent : ExtendableEvent
     getter lastChance
-    getter registration
+    getter tag
     method constructor
 interface SyncManager
     method constructor
-    method getRegistration
-    method getRegistrations
-    method permissionState
+    method getTags
     method register
-interface SyncRegistration
-    getter finished
-    getter tag
-    method constructor
-    method unregister
 interface TextDecoder
     getter encoding
     getter fatal
@@ -636,6 +629,19 @@
     setter protocol
     setter search
     setter username
+interface URLSearchParams
+    method append
+    method constructor
+    method delete
+    method entries
+    method forEach
+    method get
+    method getAll
+    method has
+    method keys
+    method set
+    method toString
+    method values
 interface WebSocket : EventTarget
     attribute CLOSED
     attribute CLOSING
diff --git a/third_party/WebKit/LayoutTests/inspector/animation/animation-empty-web-animations.html b/third_party/WebKit/LayoutTests/inspector/animation/animation-empty-web-animations.html
index 6f00ef8..cc69dd7 100644
--- a/third_party/WebKit/LayoutTests/inspector/animation/animation-empty-web-animations.html
+++ b/third_party/WebKit/LayoutTests/inspector/animation/animation-empty-web-animations.html
@@ -15,11 +15,19 @@
 
 function test()
 {
-    var timeline = new WebInspector.AnimationTimeline();
-    var elementsPanel = WebInspector.ElementsPanel.instance();
-    elementsPanel.setWidgetBelowDOM(timeline);
-    InspectorTest.addSniffer(WebInspector.AnimationModel.prototype, "animationStarted", animationStarted);
-    InspectorTest.evaluateInPage("startAnimation()");
+    InspectorTest.addSniffer(WebInspector.TabbedPane.prototype, "changeTabView", onChangeTabView, true);
+    WebInspector.inspectorView.showViewInDrawer("animations", true);
+    var timeline;
+
+    function onChangeTabView(id, view)
+    {
+        if (!timeline && id === "animations") {
+            timeline = view;
+            InspectorTest.assertTrue(timeline instanceof WebInspector.AnimationTimeline);
+            InspectorTest.evaluateInPage("startAnimation()");
+            InspectorTest.addSniffer(WebInspector.AnimationModel.prototype, "animationStarted", animationStarted);
+        }
+    }
 
     function animationStarted()
     {
diff --git a/third_party/WebKit/LayoutTests/inspector/animation/animation-timeline.html b/third_party/WebKit/LayoutTests/inspector/animation/animation-timeline.html
index 2c31d4ae..4c86c0ad 100644
--- a/third_party/WebKit/LayoutTests/inspector/animation/animation-timeline.html
+++ b/third_party/WebKit/LayoutTests/inspector/animation/animation-timeline.html
@@ -55,20 +55,23 @@
 
 function test()
 {
-    InspectorTest.selectNodeWithId("node", step1);
-    var timeline = new WebInspector.AnimationTimeline();
-    var elementsPanel = WebInspector.ElementsPanel.instance();
-    elementsPanel.setWidgetBelowDOM(timeline);
     // Override timeline width for testing
     WebInspector.AnimationTimeline.prototype.width = function() { return 1000; }
     // Override animation color for testing
     // FIXME: Set animation name of Web Animation instead; not supported yet
     WebInspector.AnimationUI.Color = function() { return "black"; }
+    var timeline;
+    InspectorTest.addSniffer(WebInspector.TabbedPane.prototype, "changeTabView", onChangeTabView, true);
+    WebInspector.inspectorView.showViewInDrawer("animations", true);
 
-    function step1()
+    function onChangeTabView(id, view)
     {
-        InspectorTest.waitForAnimationAdded(step2);
-        InspectorTest.evaluateInPage("startAnimationWithDelay()");
+        if (!timeline && id === "animations") {
+            timeline = view;
+            InspectorTest.assertTrue(timeline instanceof WebInspector.AnimationTimeline);
+            InspectorTest.waitForAnimationAdded(step2);
+            InspectorTest.evaluateInPage("startAnimationWithDelay()");
+        }
     }
 
     function step2(group)
diff --git a/third_party/WebKit/LayoutTests/inspector/elements/css-rule-hover-highlights-selectors-expected.txt b/third_party/WebKit/LayoutTests/inspector/elements/css-rule-hover-highlights-selectors-expected.txt
new file mode 100644
index 0000000..a72976f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/inspector/elements/css-rule-hover-highlights-selectors-expected.txt
@@ -0,0 +1,9 @@
+
+Running: setupProxyOverlay
+
+Running: testRegularNodeSelection
+Highlights drawn: 4
+
+Running: testShadowDOMNodeSelection
+Highlights drawn: 6
+
diff --git a/third_party/WebKit/LayoutTests/inspector/elements/css-rule-hover-highlights-selectors.html b/third_party/WebKit/LayoutTests/inspector/elements/css-rule-hover-highlights-selectors.html
new file mode 100644
index 0000000..2f65e41
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/inspector/elements/css-rule-hover-highlights-selectors.html
@@ -0,0 +1,138 @@
+<html>
+<head>
+<script src="../../http/tests/inspector/inspector-test.js"></script>
+<script src="../../http/tests/inspector/elements-test.js"></script>
+<style>
+.border {
+    border: 1px solid black;
+}
+</style>
+<script>
+
+function buildShadowDOM()
+{
+    var host = document.querySelector("body");
+    var root = host.createShadowRoot();
+    var template = document.querySelector("#dom-template");
+    var clone = document.importNode(template.content, true);
+    root.appendChild(clone);
+    var second = root.querySelector("#fifth");
+    second.id = "inspected-shadow";
+    runTest();
+}
+
+function test()
+{
+    InspectorTest.runTestSuite([
+        function setupProxyOverlay(next)
+        {
+            InspectorTest.evaluateFunctionInOverlay(drawHighlightProxy, next);
+        },
+
+        function testRegularNodeSelection(next)
+        {
+            InspectorTest.selectNodeAndWaitForStyles("inspected", onSelected);
+
+            function onSelected()
+            {
+                resetHighlightCount(onHighlightCountReset);
+            }
+
+            function onHighlightCountReset()
+            {
+                var section = InspectorTest.firstMatchedStyleSection();
+                section._highlight();
+                testRunner.layoutAndPaintAsyncThen(onHighlighted);
+            }
+
+            function onHighlighted()
+            {
+                dumpHighlightCount(next);
+            }
+        },
+
+        function testShadowDOMNodeSelection(next)
+        {
+            InspectorTest.selectNodeAndWaitForStyles("inspected-shadow", onSelected);
+
+            function onSelected()
+            {
+                resetHighlightCount(onHighlightCountReset);
+            }
+
+            function onHighlightCountReset()
+            {
+                var section = InspectorTest.firstMatchedStyleSection();
+                section._highlight();
+                testRunner.layoutAndPaintAsyncThen(onHighlighted);
+            }
+
+            function onHighlighted()
+            {
+                dumpHighlightCount(next);
+            }
+        },
+    ]);
+
+    function drawHighlightProxy()
+    {
+        window._highlightsForTest = [];
+        var oldDrawHighlight = drawHighlight;
+        drawHighlight = proxy;
+
+        function proxy(highlight, context)
+        {
+            window._highlightsForTest.push(highlight);
+            oldDrawHighlight(highlight, context);
+        }
+    }
+
+    function reportHighlights()
+    {
+        var result = window._highlightsForTest.length;
+        window._highlightsForTest = [];
+        return result + "";
+    }
+
+    function dumpHighlightCount(next)
+    {
+        InspectorTest.evaluateFunctionInOverlay(reportHighlights, onResults);
+
+        function onResults(count)
+        {
+            InspectorTest.addResult("Highlights drawn: " + count);
+            next();
+        }
+    }
+
+    function resetHighlightCount(next)
+    {
+        InspectorTest.evaluateFunctionInOverlay(reportHighlights, next);
+    }
+}
+
+</script>
+</head>
+
+<body onload="buildShadowDOM()">
+<p>
+Tests that long-hovering over StylesSidebar matched rule selector highlights
+matching nodes in the page.
+</p>
+<div class="border">1st</div>
+<div id="inspected" class="border">2nd</div>
+<div class="border">3rd</div>
+<template id="dom-template">
+    <style>
+    .bck {
+        border: 1px solid black;
+    }
+    </style>
+    <div class="bck">1st</div>
+    <div class="bck">2nd</div>
+    <div class="bck">3rd</div>
+    <div class="bck">4th</div>
+    <div class="bck" id="fifth">5th</div>
+</template>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/svg/custom/baseuri-href-expected.html b/third_party/WebKit/LayoutTests/svg/custom/baseuri-href-expected.html
new file mode 100644
index 0000000..75768a0
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/svg/custom/baseuri-href-expected.html
@@ -0,0 +1,5 @@
+<!DOCTYPE html>
+<svg>
+   <rect id="rect" width="100" height="100" fill="green"/>
+</svg>
+
diff --git a/third_party/WebKit/LayoutTests/svg/custom/baseuri-href.html b/third_party/WebKit/LayoutTests/svg/custom/baseuri-href.html
new file mode 100644
index 0000000..731a0b0
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/svg/custom/baseuri-href.html
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<base href="/foo"/>
+<svg>
+  <rect id="rect" width="100" height="100" fill="green"/>                          
+  <use xlink:href="#rect" x="150"/>
+</svg>
+
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 48d165e3..36dedba4 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
@@ -528,6 +528,19 @@
     setter protocol
     setter search
     setter username
+interface URLSearchParams
+    method append
+    method constructor
+    method delete
+    method entries
+    method forEach
+    method get
+    method getAll
+    method has
+    method keys
+    method set
+    method toString
+    method values
 interface WebSocket : EventTarget
     attribute CLOSED
     attribute CLOSING
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 886ce38..bb0e7c2 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
@@ -514,6 +514,19 @@
 [Worker]     setter protocol
 [Worker]     setter search
 [Worker]     setter username
+[Worker] interface URLSearchParams
+[Worker]     method append
+[Worker]     method constructor
+[Worker]     method delete
+[Worker]     method entries
+[Worker]     method forEach
+[Worker]     method get
+[Worker]     method getAll
+[Worker]     method has
+[Worker]     method keys
+[Worker]     method set
+[Worker]     method toString
+[Worker]     method values
 [Worker] interface WebSocket : EventTarget
 [Worker]     attribute CLOSED
 [Worker]     attribute CLOSING
diff --git a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt
index ba13e8c..4311a8b 100644
--- a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -4750,6 +4750,19 @@
     setter protocol
     setter search
     setter username
+interface URLSearchParams
+    method append
+    method constructor
+    method delete
+    method entries
+    method forEach
+    method get
+    method getAll
+    method has
+    method keys
+    method set
+    method toString
+    method values
 interface VTTCue : TextTrackCue
     getter align
     getter line
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 9af80ab..d53d411 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
@@ -506,6 +506,19 @@
 [Worker]     setter protocol
 [Worker]     setter search
 [Worker]     setter username
+[Worker] interface URLSearchParams
+[Worker]     method append
+[Worker]     method constructor
+[Worker]     method delete
+[Worker]     method entries
+[Worker]     method forEach
+[Worker]     method get
+[Worker]     method getAll
+[Worker]     method has
+[Worker]     method keys
+[Worker]     method set
+[Worker]     method toString
+[Worker]     method values
 [Worker] interface WebSocket : EventTarget
 [Worker]     attribute CLOSED
 [Worker]     attribute CLOSING
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 b71358c..843ac62 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
@@ -579,6 +579,19 @@
 [Worker]     setter protocol
 [Worker]     setter search
 [Worker]     setter username
+[Worker] interface URLSearchParams
+[Worker]     method append
+[Worker]     method constructor
+[Worker]     method delete
+[Worker]     method entries
+[Worker]     method forEach
+[Worker]     method get
+[Worker]     method getAll
+[Worker]     method has
+[Worker]     method keys
+[Worker]     method set
+[Worker]     method toString
+[Worker]     method values
 [Worker] interface WebSocket : EventTarget
 [Worker]     attribute CLOSED
 [Worker]     attribute CLOSING
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 f468c4a4..33088f5 100644
--- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -5160,15 +5160,8 @@
     method wrapKey
 interface SyncManager
     method constructor
-    method getRegistration
-    method getRegistrations
-    method permissionState
+    method getTags
     method register
-interface SyncRegistration
-    getter finished
-    getter tag
-    method constructor
-    method unregister
 interface Text : CharacterData
     getter wholeText
     method constructor
@@ -5347,6 +5340,19 @@
     setter protocol
     setter search
     setter username
+interface URLSearchParams
+    method append
+    method constructor
+    method delete
+    method entries
+    method forEach
+    method get
+    method getAll
+    method has
+    method keys
+    method set
+    method toString
+    method values
 interface USBAlternateInterface
     getter alternateSetting
     getter endpoints
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 01ec856..c0d05bc 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
@@ -571,6 +571,19 @@
 [Worker]     setter protocol
 [Worker]     setter search
 [Worker]     setter username
+[Worker] interface URLSearchParams
+[Worker]     method append
+[Worker]     method constructor
+[Worker]     method delete
+[Worker]     method entries
+[Worker]     method forEach
+[Worker]     method get
+[Worker]     method getAll
+[Worker]     method has
+[Worker]     method keys
+[Worker]     method set
+[Worker]     method toString
+[Worker]     method values
 [Worker] interface WebSocket : EventTarget
 [Worker]     attribute CLOSED
 [Worker]     attribute CLOSING
diff --git a/third_party/WebKit/Source/core/core.gypi b/third_party/WebKit/Source/core/core.gypi
index 65788117..c1551df6 100644
--- a/third_party/WebKit/Source/core/core.gypi
+++ b/third_party/WebKit/Source/core/core.gypi
@@ -96,6 +96,7 @@
             'dom/Uint32Array.idl',
             'dom/Uint8Array.idl',
             'dom/Uint8ClampedArray.idl',
+            'dom/URLSearchParams.idl',
             'dom/XMLDocument.idl',
             'dom/shadow/ShadowRoot.idl',
             'editing/Selection.idl',
@@ -2501,6 +2502,8 @@
             'dom/TreeShared.h',
             'dom/TreeWalker.cpp',
             'dom/TreeWalker.h',
+            'dom/URLSearchParams.cpp',
+            'dom/URLSearchParams.h',
             'dom/UserActionElementSet.cpp',
             'dom/UserActionElementSet.h',
             'dom/ViewportDescription.cpp',
diff --git a/third_party/WebKit/Source/core/css/CSSCustomFontData.h b/third_party/WebKit/Source/core/css/CSSCustomFontData.h
index 3ca52da..227adfcd 100644
--- a/third_party/WebKit/Source/core/css/CSSCustomFontData.h
+++ b/third_party/WebKit/Source/core/css/CSSCustomFontData.h
@@ -23,6 +23,7 @@
 
 #include "core/css/CSSFontFaceSource.h"
 #include "platform/fonts/CustomFontData.h"
+#include "platform/heap/Handle.h"
 
 namespace blink {
 
@@ -66,11 +67,13 @@
             m_isLoading = source->isLoading();
     }
 
-    RemoteFontFaceSource* m_fontFaceSource;
+    // TODO(Oilpan): consider moving (Custom)FontFace hierarchy to the heap,
+    // thereby making this reference a Member<>.
+    RawPtrWillBeWeakPersistent<RemoteFontFaceSource> m_fontFaceSource;
     FallbackVisibility m_fallbackVisibility;
     mutable bool m_isLoading;
 };
 
-}
+} // namespace blink
 
 #endif // CSSCustomFontData_h
diff --git a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
index c71f7787..05d1644 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
+++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
@@ -1775,6 +1775,56 @@
     return consumeColor(range, context);
 }
 
+static PassRefPtrWillBeRawPtr<CSSValue> consumePaintOrder(CSSParserTokenRange& range)
+{
+    if (range.peek().id() == CSSValueNormal)
+        return consumeIdent(range);
+
+    Vector<CSSValueID, 3> paintTypeList;
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> fill = nullptr;
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> stroke = nullptr;
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> markers = nullptr;
+    do {
+        CSSValueID id = range.peek().id();
+        if (id == CSSValueFill && !fill)
+            fill = consumeIdent(range);
+        else if (id == CSSValueStroke && !stroke)
+            stroke = consumeIdent(range);
+        else if (id == CSSValueMarkers && !markers)
+            markers = consumeIdent(range);
+        else
+            return nullptr;
+        paintTypeList.append(id);
+    } while (!range.atEnd());
+
+    // After parsing we serialize the paint-order list. Since it is not possible to
+    // pop a last list items from CSSValueList without bigger cost, we create the
+    // list after parsing.
+    CSSValueID firstPaintOrderType = paintTypeList.at(0);
+    RefPtrWillBeRawPtr<CSSValueList> paintOrderList = CSSValueList::createSpaceSeparated();
+    switch (firstPaintOrderType) {
+    case CSSValueFill:
+    case CSSValueStroke:
+        paintOrderList->append(firstPaintOrderType == CSSValueFill ? fill.release() : stroke.release());
+        if (paintTypeList.size() > 1) {
+            if (paintTypeList.at(1) == CSSValueMarkers)
+                paintOrderList->append(markers.release());
+        }
+        break;
+    case CSSValueMarkers:
+        paintOrderList->append(markers.release());
+        if (paintTypeList.size() > 1) {
+            if (paintTypeList.at(1) == CSSValueStroke)
+                paintOrderList->append(stroke.release());
+        }
+        break;
+    default:
+        ASSERT_NOT_REACHED();
+    }
+
+    return paintOrderList.release();
+}
+
 PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseSingleValue(CSSPropertyID unresolvedProperty)
 {
     CSSPropertyID property = resolveCSSPropertyID(unresolvedProperty);
@@ -1929,6 +1979,8 @@
     case CSSPropertyFill:
     case CSSPropertyStroke:
         return consumePaint(m_range, m_context);
+    case CSSPropertyPaintOrder:
+        return consumePaintOrder(m_range);
     default:
         return nullptr;
     }
diff --git a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.h b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.h
index 3afdcd3..ba0aff0 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.h
+++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.h
@@ -199,8 +199,6 @@
     bool parseSVGValue(CSSPropertyID propId, bool important);
     PassRefPtrWillBeRawPtr<CSSValue> parseSVGStrokeDasharray();
 
-    PassRefPtrWillBeRawPtr<CSSValue> parsePaintOrder() const;
-
     // CSS3 Parsing Routines (for properties specific to CSS3)
     bool parseBorderImageShorthand(CSSPropertyID, bool important);
     PassRefPtrWillBeRawPtr<CSSValue> parseBorderImage(CSSPropertyID);
diff --git a/third_party/WebKit/Source/core/css/parser/LegacyCSSPropertyParser.cpp b/third_party/WebKit/Source/core/css/parser/LegacyCSSPropertyParser.cpp
index 10a9dbd..66060031 100644
--- a/third_party/WebKit/Source/core/css/parser/LegacyCSSPropertyParser.cpp
+++ b/third_party/WebKit/Source/core/css/parser/LegacyCSSPropertyParser.cpp
@@ -1172,6 +1172,7 @@
     case CSSPropertyStopColor:
     case CSSPropertyFloodColor:
     case CSSPropertyLightingColor:
+    case CSSPropertyPaintOrder:
         validPrimitive = false;
         break;
 
@@ -5501,13 +5502,6 @@
      * correctly and allows optimization in applyRule(..)
      */
 
-    case CSSPropertyPaintOrder:
-        if (m_valueList->size() == 1 && id == CSSValueNormal)
-            validPrimitive = true;
-        else if ((parsedValue = parsePaintOrder()))
-            m_valueList->next();
-        break;
-
     case CSSPropertyStrokeWidth: // <length> | inherit
     case CSSPropertyStrokeDashoffset:
     case CSSPropertyCx:
@@ -5600,58 +5594,4 @@
     return ret.release();
 }
 
-// normal | [ fill || stroke || markers ]
-PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parsePaintOrder() const
-{
-    if (m_valueList->size() > 3)
-        return nullptr;
-
-    CSSParserValue* value = m_valueList->current();
-    ASSERT(value);
-
-    Vector<CSSValueID, 3> paintTypeList;
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> fill = nullptr;
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> stroke = nullptr;
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> markers = nullptr;
-    while (value) {
-        if (value->id == CSSValueFill && !fill)
-            fill = CSSPrimitiveValue::createIdentifier(value->id);
-        else if (value->id == CSSValueStroke && !stroke)
-            stroke = CSSPrimitiveValue::createIdentifier(value->id);
-        else if (value->id == CSSValueMarkers && !markers)
-            markers = CSSPrimitiveValue::createIdentifier(value->id);
-        else
-            return nullptr;
-        paintTypeList.append(value->id);
-        value = m_valueList->next();
-    }
-
-    // After parsing we serialize the paint-order list. Since it is not possible to
-    // pop a last list items from CSSValueList without bigger cost, we create the
-    // list after parsing.
-    CSSValueID firstPaintOrderType = paintTypeList.at(0);
-    RefPtrWillBeRawPtr<CSSValueList> paintOrderList = CSSValueList::createSpaceSeparated();
-    switch (firstPaintOrderType) {
-    case CSSValueFill:
-    case CSSValueStroke:
-        paintOrderList->append(firstPaintOrderType == CSSValueFill ? fill.release() : stroke.release());
-        if (paintTypeList.size() > 1) {
-            if (paintTypeList.at(1) == CSSValueMarkers)
-                paintOrderList->append(markers.release());
-        }
-        break;
-    case CSSValueMarkers:
-        paintOrderList->append(markers.release());
-        if (paintTypeList.size() > 1) {
-            if (paintTypeList.at(1) == CSSValueStroke)
-                paintOrderList->append(stroke.release());
-        }
-        break;
-    default:
-        ASSERT_NOT_REACHED();
-    }
-
-    return paintOrderList.release();
-}
-
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/dom/URLSearchParams.cpp b/third_party/WebKit/Source/core/dom/URLSearchParams.cpp
new file mode 100644
index 0000000..141aab146
--- /dev/null
+++ b/third_party/WebKit/Source/core/dom/URLSearchParams.cpp
@@ -0,0 +1,188 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/dom/URLSearchParams.h"
+
+#include "platform/weborigin/KURL.h"
+#include "wtf/text/StringBuilder.h"
+#include "wtf/text/TextEncoding.h"
+
+namespace blink {
+
+namespace {
+
+class URLSearchParamsIterationSource final : public PairIterable<String, String>::IterationSource {
+public:
+    URLSearchParamsIterationSource(Vector<std::pair<String, String>> params) : m_params(params), m_current(0) { }
+
+    bool next(ScriptState*, String& key, String& value, ExceptionState&) override
+    {
+        if (m_current >= m_params.size())
+            return false;
+
+        key = m_params[m_current].first;
+        value = m_params[m_current].second;
+        m_current++;
+        return true;
+    }
+
+private:
+    Vector<std::pair<String, String>> m_params;
+    size_t m_current;
+};
+
+} // namespace
+
+URLSearchParams* URLSearchParams::create(const URLSearchParamsInit& init)
+{
+    if (init.isUSVString())
+        return new URLSearchParams(init.getAsUSVString());
+    if (init.isURLSearchParams())
+        return new URLSearchParams(init.getAsURLSearchParams());
+
+    ASSERT(init.isNull());
+    return new URLSearchParams(String());
+}
+
+URLSearchParams::URLSearchParams(const String& queryString)
+{
+    if (!queryString.isEmpty())
+        setInput(queryString);
+}
+
+URLSearchParams::URLSearchParams(URLSearchParams* searchParams)
+{
+    ASSERT(searchParams);
+    m_params = searchParams->m_params;
+}
+
+URLSearchParams::~URLSearchParams()
+{
+}
+
+static String decodeString(String input)
+{
+    return decodeURLEscapeSequences(input.replace('+', ' '));
+}
+
+void URLSearchParams::setInput(const String& queryString)
+{
+    ASSERT(m_params.isEmpty());
+    size_t start = 0;
+    size_t queryStringLength = queryString.length();
+    while (start < queryStringLength) {
+        size_t nameStart = start;
+        size_t nameValueEnd = queryString.find('&', start);
+        if (nameValueEnd == kNotFound)
+            nameValueEnd = queryStringLength;
+        if (nameValueEnd > start) {
+            size_t endOfName = queryString.find('=', start);
+            if (endOfName == kNotFound || endOfName > nameValueEnd)
+                endOfName = nameValueEnd;
+            String name = decodeString(queryString.substring(nameStart, endOfName - nameStart));
+            String value;
+            if (endOfName != nameValueEnd)
+                value = decodeString(queryString.substring(endOfName + 1, nameValueEnd - endOfName - 1));
+            if (value.isNull())
+                value = "";
+            m_params.append(std::make_pair(name, value));
+        }
+        start = nameValueEnd + 1;
+    }
+}
+static String encodeString(const String& input)
+{
+    return encodeWithURLEscapeSequences(input).replace("%20", "+");
+}
+
+String URLSearchParams::toString() const
+{
+    StringBuilder result;
+    for (size_t i = 0; i < m_params.size(); ++i) {
+        if (i)
+            result.append('&');
+        result.append(encodeString(m_params[i].first));
+        result.append('=');
+        result.append(encodeString(m_params[i].second));
+    }
+    return result.toString();
+}
+
+void URLSearchParams::append(const String& name, const String& value)
+{
+    m_params.append(std::make_pair(name, value));
+}
+
+void URLSearchParams::deleteAllWithName(const String& name)
+{
+    for (size_t i = 0; i < m_params.size();) {
+        if (m_params[i].first == name)
+            m_params.remove(i);
+        else
+            i++;
+    }
+}
+
+String URLSearchParams::get(const String& name) const
+{
+    for (const auto& param : m_params) {
+        if (param.first == name)
+            return param.second;
+    }
+    return String();
+}
+
+Vector<String> URLSearchParams::getAll(const String& name) const
+{
+    Vector<String> result;
+    for (const auto& param : m_params) {
+        if (param.first == name)
+            result.append(param.second);
+    }
+    return result;
+}
+
+bool URLSearchParams::has(const String& name) const
+{
+    for (const auto& param : m_params) {
+        if (param.first == name)
+            return true;
+    }
+    return false;
+}
+
+void URLSearchParams::set(const String& name, const String& value)
+{
+    bool foundMatch = false;
+    for (size_t i = 0; i < m_params.size();) {
+        // If there are any name-value whose name is 'name', set
+        // the value of the first such name-value pair to 'value'
+        // and remove the others.
+        if (m_params[i].first == name) {
+            if (!foundMatch) {
+                m_params[i++].second = value;
+                foundMatch = true;
+            } else {
+                m_params.remove(i);
+            }
+        } else {
+            i++;
+        }
+    }
+    // Otherwise, append a new name-value pair to the list.
+    if (!foundMatch)
+        append(name, value);
+}
+
+DEFINE_TRACE(URLSearchParams)
+{
+}
+
+PairIterable<String, String>::IterationSource* URLSearchParams::startIteration(ScriptState*, ExceptionState&)
+{
+    return new URLSearchParamsIterationSource(m_params);
+}
+
+} // namespace blink
diff --git a/third_party/WebKit/Source/core/dom/URLSearchParams.h b/third_party/WebKit/Source/core/dom/URLSearchParams.h
new file mode 100644
index 0000000..7eb3dfbe
--- /dev/null
+++ b/third_party/WebKit/Source/core/dom/URLSearchParams.h
@@ -0,0 +1,58 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef URLSearchParams_h
+#define URLSearchParams_h
+
+#include "bindings/core/v8/Iterable.h"
+#include "bindings/core/v8/ScriptWrappable.h"
+#include "bindings/core/v8/UnionTypesCore.h"
+#include "platform/heap/Handle.h"
+#include "wtf/Forward.h"
+#include "wtf/text/WTFString.h"
+#include <utility>
+
+namespace blink {
+
+class ExceptionState;
+
+typedef USVStringOrURLSearchParams URLSearchParamsInit;
+
+class CORE_EXPORT URLSearchParams final : public GarbageCollectedFinalized<URLSearchParams>, public ScriptWrappable, public PairIterable<String, String> {
+    DEFINE_WRAPPERTYPEINFO();
+
+public:
+    // TODO(mkwst): We should support integration with URLUtils, as explored in
+    // https://codereview.chromium.org/143313002/. That approach is totally
+    // reasonable, but relies on Node switching to Oilpan. Sigbjorn assures me
+    // that this will happen Real Soon Now(tm).
+    static URLSearchParams* create(const URLSearchParamsInit&);
+
+    // TODO(mkwst): ScriptWrappable doesn't have a destructor with Oilpan, so this
+    // won't need to be virtual once that's the default.
+    virtual ~URLSearchParams();
+
+    // URLSearchParams interface methods
+    String toString() const;
+    void append(const String& name, const String& value);
+    void deleteAllWithName(const String&);
+    String get(const String&) const;
+    Vector<String> getAll(const String&) const;
+    bool has(const String&) const;
+    void set(const String& name, const String& value);
+    void setInput(const String&);
+
+    DECLARE_TRACE();
+
+private:
+    explicit URLSearchParams(const String&);
+    explicit URLSearchParams(URLSearchParams*);
+    Vector<std::pair<String, String>> m_params;
+
+    IterationSource* startIteration(ScriptState*, ExceptionState&) override;
+};
+
+} // namespace blink
+
+#endif // URLSearchParams_h
diff --git a/third_party/WebKit/Source/core/dom/URLSearchParams.idl b/third_party/WebKit/Source/core/dom/URLSearchParams.idl
new file mode 100644
index 0000000..409542c
--- /dev/null
+++ b/third_party/WebKit/Source/core/dom/URLSearchParams.idl
@@ -0,0 +1,21 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// https://url.spec.whatwg.org/#interface-urlsearchparams
+
+[
+    Constructor(optional (USVString or URLSearchParams) init = ""),
+    GarbageCollected,
+    Exposed=(Window,Worker)
+] interface URLSearchParams {
+    void append(USVString name, USVString value);
+    [ImplementedAs=deleteAllWithName] void delete(USVString name);
+    USVString? get(USVString name);
+    sequence<USVString> getAll(USVString name);
+    boolean has(USVString name);
+    void set(USVString name, USVString value);
+    
+    iterable<USVString, USVString>;
+    stringifier;
+};
diff --git a/third_party/WebKit/Source/core/frame/UseCounter.h b/third_party/WebKit/Source/core/frame/UseCounter.h
index afc2599..895bda7f 100644
--- a/third_party/WebKit/Source/core/frame/UseCounter.h
+++ b/third_party/WebKit/Source/core/frame/UseCounter.h
@@ -884,6 +884,7 @@
         CSSFilterContrast = 1022,
         CSSFilterBlur = 1023,
         CSSFilterDropShadow = 1024,
+        BackgroundSyncRegister = 1025,
 
         // Add new features immediately above this line. Don't change assigned
         // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/WebKit/Source/core/frame/VisualViewport.cpp b/third_party/WebKit/Source/core/frame/VisualViewport.cpp
index eb0b002..e213c0895 100644
--- a/third_party/WebKit/Source/core/frame/VisualViewport.cpp
+++ b/third_party/WebKit/Source/core/frame/VisualViewport.cpp
@@ -579,7 +579,12 @@
     return m_overlayScrollbarVertical.get();
 }
 
-void VisualViewport::paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect* inClip) const
+IntRect VisualViewport::computeInterestRect(const GraphicsLayer*, const IntRect&) const
+{
+    return IntRect();
+}
+
+void VisualViewport::paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect&) const
 {
 }
 
@@ -719,7 +724,7 @@
         || (constraints.minimumScale == constraints.maximumScale && constraints.minimumScale != -1);
 }
 
-String VisualViewport::debugName(const GraphicsLayer* graphicsLayer)
+String VisualViewport::debugName(const GraphicsLayer* graphicsLayer) const
 {
     String name;
     if (graphicsLayer == m_innerViewportContainerLayer.get()) {
diff --git a/third_party/WebKit/Source/core/frame/VisualViewport.h b/third_party/WebKit/Source/core/frame/VisualViewport.h
index 98dbd75..5538abd 100644
--- a/third_party/WebKit/Source/core/frame/VisualViewport.h
+++ b/third_party/WebKit/Source/core/frame/VisualViewport.h
@@ -210,8 +210,9 @@
     bool visualViewportSuppliesScrollbars() const;
 
     // GraphicsLayerClient implementation.
-    void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect* inClip) const override;
-    String debugName(const GraphicsLayer*) override;
+    IntRect computeInterestRect(const GraphicsLayer*, const IntRect&) const;
+    void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect&) const override;
+    String debugName(const GraphicsLayer*) const override;
 
     void setupScrollbar(WebScrollbar::Orientation);
     FloatPoint clampOffsetToBoundaries(const FloatPoint&);
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
index b8440dc0..d61ec02 100644
--- a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
+++ b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
@@ -2191,7 +2191,7 @@
 // cc::DisplayListRecordingSource::UpdateAndExpandInvalidation() before we keep only one copy of the algorithm.
 static const int kPixelDistanceToRecord = 4000;
 
-IntRect CompositedLayerMapping::computeInterestRect(const GraphicsLayer* graphicsLayer, LayoutObject* owningLayoutObject)
+IntRect CompositedLayerMapping::recomputeInterestRect(const GraphicsLayer* graphicsLayer, LayoutObject* owningLayoutObject)
 {
     FloatRect graphicsLayerBounds(FloatPoint(), graphicsLayer->size());
 
@@ -2256,33 +2256,23 @@
     return false;
 }
 
-void CompositedLayerMapping::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase graphicsLayerPaintingPhase, const IntRect* interestRect) const
+IntRect CompositedLayerMapping::computeInterestRect(const GraphicsLayer* graphicsLayer, const IntRect& previousInterestRect) const
 {
-    IntRect defaultInterestRect;
-    if (RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEnabled()) {
-        if (!interestRect) {
-            if (graphicsLayer == m_graphicsLayer || graphicsLayer == m_squashingLayer)
-                defaultInterestRect = computeInterestRect(graphicsLayer, m_owningLayer.layoutObject());
-            else
-                defaultInterestRect = enclosingIntRect(FloatRect(FloatPoint(), graphicsLayer->size()));
-            interestRect = &defaultInterestRect;
-        }
+    if (graphicsLayer != m_graphicsLayer && graphicsLayer != m_squashingLayer)
+        return IntRect(IntPoint(), expandedIntSize(graphicsLayer->size()));
 
-        if (!m_owningLayer.needsRepaint()
-            && !context.paintController().cacheIsEmpty()
-            && !interestRectChangedEnoughToRepaint(m_previousPaintInterestRect, *interestRect, expandedIntSize(graphicsLayer->size()))) {
-            context.paintController().createAndAppend<CachedDisplayItem>(*this, DisplayItem::CachedDisplayItemList);
-            return;
-        }
-
-        m_previousPaintInterestRect = *interestRect;
-    }
-
-    ASSERT(interestRect);
-    paintContentsInternal(graphicsLayer, context, graphicsLayerPaintingPhase, *interestRect);
+    IntRect newInterestRect = recomputeInterestRect(graphicsLayer, m_owningLayer.layoutObject());
+    if (interestRectChangedEnoughToRepaint(previousInterestRect, newInterestRect, expandedIntSize(graphicsLayer->size())))
+        return newInterestRect;
+    return previousInterestRect;
 }
 
-void CompositedLayerMapping::paintContentsInternal(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase graphicsLayerPaintingPhase, const IntRect& interestRect) const
+bool CompositedLayerMapping::needsRepaint() const
+{
+    return m_owningLayer.needsRepaint();
+}
+
+void CompositedLayerMapping::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase graphicsLayerPaintingPhase, const IntRect& interestRect) const
 {
     // https://code.google.com/p/chromium/issues/detail?id=343772
     DisableCompositingQueryAsserts disabler;
@@ -2481,7 +2471,7 @@
     }
 }
 
-String CompositedLayerMapping::debugName(const GraphicsLayer* graphicsLayer)
+String CompositedLayerMapping::debugName(const GraphicsLayer* graphicsLayer) const
 {
     String name;
     if (graphicsLayer == m_graphicsLayer.get()) {
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h
index a479f84d..758b9ca 100644
--- a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h
+++ b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h
@@ -154,7 +154,10 @@
     void notifyFirstTextPaint() override;
     void notifyFirstImagePaint() override;
 
-    void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect* clip) const override;
+    IntRect computeInterestRect(const GraphicsLayer*, const IntRect& previousInterestRect) const override;
+    bool needsRepaint() const override;
+    void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect& interestRect) const override;
+
     bool isTrackingPaintInvalidations() const override;
 
 #if ENABLE(ASSERT)
@@ -194,7 +197,7 @@
     void assertNeedsToUpdateGraphicsLayerBitsCleared() {  ASSERT(m_pendingUpdateScope == GraphicsLayerUpdateNone); }
 #endif
 
-    String debugName(const GraphicsLayer*) override;
+    String debugName(const GraphicsLayer*) const override;
 
     LayoutSize contentOffsetInCompositingLayer() const;
 
@@ -212,7 +215,7 @@
     String debugName() const { return "CompositedLayerMapping for " + owningLayer().debugName(); }
 
 private:
-    static IntRect computeInterestRect(const GraphicsLayer*, LayoutObject* owningLayoutObject);
+    static IntRect recomputeInterestRect(const GraphicsLayer*, LayoutObject* owningLayoutObject);
     static bool interestRectChangedEnoughToRepaint(const IntRect& previousInterestRect, const IntRect& newInterestRect, const IntSize& layerSize);
 
     static const GraphicsLayerPaintInfo* containingSquashedLayer(const LayoutObject*,  const Vector<GraphicsLayerPaintInfo>& layers, unsigned maxSquashedLayerIndex);
@@ -316,8 +319,6 @@
     // not appear earlier in the set of layers for this object.
     bool invalidateLayerIfNoPrecedingEntry(size_t);
 
-    void paintContentsInternal(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect& interestRect) const;
-
     PaintLayer& m_owningLayer;
 
     // The hierarchy of layers that is maintained by the CompositedLayerMapping looks like this:
@@ -441,8 +442,6 @@
     unsigned m_backgroundLayerPaintsFixedRootBackground : 1;
     unsigned m_scrollingContentsAreEmpty : 1;
 
-    mutable IntRect m_previousPaintInterestRect;
-
     friend class CompositedLayerMappingTest;
 };
 
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMappingTest.cpp b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMappingTest.cpp
index 0490a8a6..57e923cf 100644
--- a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMappingTest.cpp
+++ b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMappingTest.cpp
@@ -8,6 +8,7 @@
 #include "core/frame/FrameView.h"
 #include "core/layout/LayoutBoxModelObject.h"
 #include "core/layout/LayoutTestHelper.h"
+#include "core/layout/LayoutView.h"
 #include "core/paint/PaintLayer.h"
 #include <gtest/gtest.h>
 
@@ -19,9 +20,9 @@
         : m_originalSlimmingPaintSynchronizedPaintingEnabled(RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEnabled()) { }
 
 protected:
-    IntRect computeInterestRect(const GraphicsLayer* graphicsLayer, LayoutObject* owningLayoutObject)
+    IntRect recomputeInterestRect(const GraphicsLayer* graphicsLayer, LayoutObject* owningLayoutObject)
     {
-        return CompositedLayerMapping::computeInterestRect(graphicsLayer, owningLayoutObject);
+        return CompositedLayerMapping::recomputeInterestRect(graphicsLayer, owningLayoutObject);
     }
 
     bool interestRectChangedEnoughToRepaint(const IntRect& previousInterestRect, const IntRect& newInterestRect, const IntSize& layerSize)
@@ -29,6 +30,11 @@
         return CompositedLayerMapping::interestRectChangedEnoughToRepaint(previousInterestRect, newInterestRect, layerSize);
     }
 
+    IntRect previousInterestRect(const GraphicsLayer* graphicsLayer)
+    {
+        return graphicsLayer->m_previousInterestRect;
+    }
+
 private:
     void SetUp() override
     {
@@ -48,22 +54,13 @@
     bool m_originalSlimmingPaintSynchronizedPaintingEnabled;
 };
 
-static void printRect(IntRect rect)
-{
-    fprintf(stderr, "[x=%d y=%d maxX=%d maxY=%d]\n", rect.x(), rect.y(), rect.maxX(), rect.maxY());
-}
-
-static bool checkRectsEqual(const IntRect& expected, const IntRect& actual)
-{
-    if (expected != actual) {
-        fprintf(stderr, "Expected: ");
-        printRect(expected);
-        fprintf(stderr, "Actual: ");
-        printRect(actual);
-        return false;
-    }
-    return true;
-}
+#define EXPECT_RECT_EQ(expected, actual) \
+    do { \
+        EXPECT_EQ(expected.x(), actual.x()); \
+        EXPECT_EQ(expected.y(), actual.y()); \
+        EXPECT_EQ(expected.width(), actual.width()); \
+        EXPECT_EQ(expected.height(), actual.height()); \
+    } while (false)
 
 TEST_F(CompositedLayerMappingTest, SimpleInterestRect)
 {
@@ -73,7 +70,7 @@
     Element* element = document().getElementById("target");
     PaintLayer* paintLayer = toLayoutBoxModelObject(element->layoutObject())->layer();
     ASSERT_TRUE(!!paintLayer->graphicsLayerBacking());
-    EXPECT_TRUE(checkRectsEqual(IntRect(0, 0, 200, 200), computeInterestRect(paintLayer->graphicsLayerBacking(), paintLayer->layoutObject())));
+    EXPECT_RECT_EQ(IntRect(0, 0, 200, 200), recomputeInterestRect(paintLayer->graphicsLayerBacking(), paintLayer->layoutObject()));
 }
 
 TEST_F(CompositedLayerMappingTest, TallLayerInterestRect)
@@ -86,7 +83,7 @@
     ASSERT_TRUE(paintLayer->graphicsLayerBacking());
     // Screen-space visible content rect is [8, 8, 200, 600]. Mapping back to local, adding 4000px in all directions, then
     // clipping, yields this rect.
-    EXPECT_TRUE(checkRectsEqual(IntRect(0, 0, 200, 4592), computeInterestRect(paintLayer->graphicsLayerBacking(), paintLayer->layoutObject())));
+    EXPECT_RECT_EQ(IntRect(0, 0, 200, 4592), recomputeInterestRect(paintLayer->graphicsLayerBacking(), paintLayer->layoutObject()));
 }
 
 TEST_F(CompositedLayerMappingTest, RotatedInterestRect)
@@ -98,7 +95,7 @@
     Element* element = document().getElementById("target");
     PaintLayer* paintLayer = toLayoutBoxModelObject(element->layoutObject())->layer();
     ASSERT_TRUE(!!paintLayer->graphicsLayerBacking());
-    EXPECT_TRUE(checkRectsEqual(IntRect(0, 0, 200, 200), computeInterestRect(paintLayer->graphicsLayerBacking(), paintLayer->layoutObject())));
+    EXPECT_RECT_EQ(IntRect(0, 0, 200, 200), recomputeInterestRect(paintLayer->graphicsLayerBacking(), paintLayer->layoutObject()));
 }
 
 TEST_F(CompositedLayerMappingTest, 3D90DegRotatedTallInterestRect)
@@ -112,7 +109,7 @@
     Element* element = document().getElementById("target");
     PaintLayer* paintLayer = toLayoutBoxModelObject(element->layoutObject())->layer();
     ASSERT_TRUE(!!paintLayer->graphicsLayerBacking());
-    EXPECT_TRUE(checkRectsEqual(IntRect(0, 0, 200, 4000), computeInterestRect(paintLayer->graphicsLayerBacking(), paintLayer->layoutObject())));
+    EXPECT_RECT_EQ(IntRect(0, 0, 200, 4000), recomputeInterestRect(paintLayer->graphicsLayerBacking(), paintLayer->layoutObject()));
 }
 
 TEST_F(CompositedLayerMappingTest, 3D45DegRotatedTallInterestRect)
@@ -124,7 +121,7 @@
     Element* element = document().getElementById("target");
     PaintLayer* paintLayer = toLayoutBoxModelObject(element->layoutObject())->layer();
     ASSERT_TRUE(!!paintLayer->graphicsLayerBacking());
-    EXPECT_TRUE(checkRectsEqual(IntRect(0, 0, 200, 4592), computeInterestRect(paintLayer->graphicsLayerBacking(), paintLayer->layoutObject())));
+    EXPECT_RECT_EQ(IntRect(0, 0, 200, 4592), recomputeInterestRect(paintLayer->graphicsLayerBacking(), paintLayer->layoutObject()));
 }
 
 TEST_F(CompositedLayerMappingTest, RotatedTallInterestRect)
@@ -136,7 +133,7 @@
     Element* element = document().getElementById("target");
     PaintLayer* paintLayer = toLayoutBoxModelObject(element->layoutObject())->layer();
     ASSERT_TRUE(!!paintLayer->graphicsLayerBacking());
-    EXPECT_TRUE(checkRectsEqual(IntRect(0, 0, 200, 4000), computeInterestRect(paintLayer->graphicsLayerBacking(), paintLayer->layoutObject())));
+    EXPECT_RECT_EQ(IntRect(0, 0, 200, 4000), recomputeInterestRect(paintLayer->graphicsLayerBacking(), paintLayer->layoutObject()));
 }
 
 TEST_F(CompositedLayerMappingTest, WideLayerInterestRect)
@@ -149,7 +146,7 @@
     ASSERT_TRUE(!!paintLayer->graphicsLayerBacking());
     // Screen-space visible content rect is [8, 8, 800, 200] (the screen is 800x600).
     // Mapping back to local, adding 4000px in all directions, then clipping, yields this rect.
-    EXPECT_TRUE(checkRectsEqual(IntRect(0, 0, 4792, 200), computeInterestRect(paintLayer->graphicsLayerBacking(), paintLayer->layoutObject())));
+    EXPECT_RECT_EQ(IntRect(0, 0, 4792, 200), recomputeInterestRect(paintLayer->graphicsLayerBacking(), paintLayer->layoutObject()));
 }
 
 TEST_F(CompositedLayerMappingTest, FixedPositionInterestRect)
@@ -161,7 +158,7 @@
     Element* element = document().getElementById("target");
     PaintLayer* paintLayer = toLayoutBoxModelObject(element->layoutObject())->layer();
     ASSERT_TRUE(!!paintLayer->graphicsLayerBacking());
-    EXPECT_TRUE(checkRectsEqual(IntRect(0, 0, 300, 400), computeInterestRect(paintLayer->graphicsLayerBacking(), paintLayer->layoutObject())));
+    EXPECT_RECT_EQ(IntRect(0, 0, 300, 400), recomputeInterestRect(paintLayer->graphicsLayerBacking(), paintLayer->layoutObject()));
 }
 
 TEST_F(CompositedLayerMappingTest, LayerOffscreenInterestRect)
@@ -175,7 +172,7 @@
     PaintLayer* paintLayer = toLayoutBoxModelObject(element->layoutObject())->layer();
     ASSERT_TRUE(!!paintLayer->graphicsLayerBacking());
     // Offscreen layers are painted as usual.
-    EXPECT_TRUE(checkRectsEqual(IntRect(0, 0, 200, 200), computeInterestRect(paintLayer->graphicsLayerBacking(), paintLayer->layoutObject())));
+    EXPECT_RECT_EQ(IntRect(0, 0, 200, 200), recomputeInterestRect(paintLayer->graphicsLayerBacking(), paintLayer->layoutObject()));
 }
 
 TEST_F(CompositedLayerMappingTest, ScrollingLayerInterestRect)
@@ -191,7 +188,7 @@
     ASSERT_TRUE(paintLayer->graphicsLayerBacking());
     // Offscreen layers are painted as usual.
     ASSERT_TRUE(paintLayer->compositedLayerMapping()->scrollingLayer());
-    EXPECT_TRUE(checkRectsEqual(IntRect(0, 0, 195, 4592), computeInterestRect(paintLayer->graphicsLayerBackingForScrolling(), paintLayer->layoutObject())));
+    EXPECT_RECT_EQ(IntRect(0, 0, 195, 4592), recomputeInterestRect(paintLayer->graphicsLayerBackingForScrolling(), paintLayer->layoutObject()));
 }
 
 TEST_F(CompositedLayerMappingTest, ClippedBigLayer)
@@ -205,7 +202,7 @@
     PaintLayer* paintLayer = toLayoutBoxModelObject(element->layoutObject())->layer();
     ASSERT_TRUE(paintLayer->graphicsLayerBacking());
     // Offscreen layers are painted as usual.
-    EXPECT_TRUE(checkRectsEqual(IntRect(0, 0, 4001, 4001), computeInterestRect(paintLayer->graphicsLayerBacking(), paintLayer->layoutObject())));
+    EXPECT_RECT_EQ(IntRect(0, 0, 4001, 4001), recomputeInterestRect(paintLayer->graphicsLayerBacking(), paintLayer->layoutObject()));
 }
 
 TEST_F(CompositedLayerMappingTest, ClippingMaskLayer)
@@ -306,4 +303,73 @@
     EXPECT_TRUE(interestRectChangedEnoughToRepaint(previousInterestRect, newInterestRect, layerSize));
 }
 
+TEST_F(CompositedLayerMappingTest, InterestRectChangeOnScroll)
+{
+    setBodyInnerHTML(
+        "<style>"
+        "  ::-webkit-scrollbar { width: 0; height: 0; }"
+        "  body { margin: 0; }"
+        "</style>"
+        "<div id='div' style='width: 100px; height: 10000px'>Text</div>");
+
+    document().view()->updateAllLifecyclePhases();
+    GraphicsLayer* rootScrollingLayer = document().layoutView()->layer()->graphicsLayerBackingForScrolling();
+    EXPECT_RECT_EQ(IntRect(0, 0, 800, 4600), previousInterestRect(rootScrollingLayer));
+
+    document().view()->setScrollPosition(IntPoint(0, 300), ProgrammaticScroll);
+    document().view()->updateAllLifecyclePhases();
+    // Still use the previous interest rect because the recomputed rect hasn't changed enough.
+    EXPECT_RECT_EQ(IntRect(0, 0, 800, 4900), recomputeInterestRect(rootScrollingLayer, document().layoutView()));
+    EXPECT_RECT_EQ(IntRect(0, 0, 800, 4600), previousInterestRect(rootScrollingLayer));
+
+    document().view()->setScrollPosition(IntPoint(0, 600), ProgrammaticScroll);
+    document().view()->updateAllLifecyclePhases();
+    // Use recomputed interest rect because it changed enough.
+    EXPECT_RECT_EQ(IntRect(0, 0, 800, 5200), recomputeInterestRect(rootScrollingLayer, document().layoutView()));
+    EXPECT_RECT_EQ(IntRect(0, 0, 800, 5200), previousInterestRect(rootScrollingLayer));
+
+    document().view()->setScrollPosition(IntPoint(0, 5400), ProgrammaticScroll);
+    document().view()->updateAllLifecyclePhases();
+    EXPECT_RECT_EQ(IntRect(0, 1400, 800, 8600), recomputeInterestRect(rootScrollingLayer, document().layoutView()));
+    EXPECT_RECT_EQ(IntRect(0, 1400, 800, 8600), previousInterestRect(rootScrollingLayer));
+
+    document().view()->setScrollPosition(IntPoint(0, 9000), ProgrammaticScroll);
+    document().view()->updateAllLifecyclePhases();
+    // Still use the previous interest rect because it contains the recomputed interest rect.
+    EXPECT_RECT_EQ(IntRect(0, 5000, 800, 5000), recomputeInterestRect(rootScrollingLayer, document().layoutView()));
+    EXPECT_RECT_EQ(IntRect(0, 1400, 800, 8600), previousInterestRect(rootScrollingLayer));
+
+    document().view()->setScrollPosition(IntPoint(0, 2000), ProgrammaticScroll);
+    // Use recomputed interest rect because it changed enough.
+    document().view()->updateAllLifecyclePhases();
+    EXPECT_RECT_EQ(IntRect(0, 0, 800, 6600), recomputeInterestRect(rootScrollingLayer, document().layoutView()));
+    EXPECT_RECT_EQ(IntRect(0, 0, 800, 6600), previousInterestRect(rootScrollingLayer));
+}
+
+TEST_F(CompositedLayerMappingTest, InterestRectShouldNotChangeOnPaintInvalidation)
+{
+    setBodyInnerHTML(
+        "<style>"
+        "  ::-webkit-scrollbar { width: 0; height: 0; }"
+        "  body { margin: 0; }"
+        "</style>"
+        "<div id='div' style='width: 100px; height: 10000px'>Text</div>");
+
+    GraphicsLayer* rootScrollingLayer = document().layoutView()->layer()->graphicsLayerBackingForScrolling();
+
+    document().view()->setScrollPosition(IntPoint(0, 5400), ProgrammaticScroll);
+    document().view()->updateAllLifecyclePhases();
+    document().view()->setScrollPosition(IntPoint(0, 9400), ProgrammaticScroll);
+    // The above code creates an interest rect bigger than the interest rect if recomputed now.
+    document().view()->updateAllLifecyclePhases();
+    EXPECT_RECT_EQ(IntRect(0, 5400, 800, 4600), recomputeInterestRect(rootScrollingLayer, document().layoutView()));
+    EXPECT_RECT_EQ(IntRect(0, 1400, 800, 8600), previousInterestRect(rootScrollingLayer));
+
+    // Paint invalidation and repaint should not change previous paint interest rect.
+    document().getElementById("div")->setTextContent("Change");
+    document().view()->updateAllLifecyclePhases();
+    EXPECT_RECT_EQ(IntRect(0, 5400, 800, 4600), recomputeInterestRect(rootScrollingLayer, document().layoutView()));
+    EXPECT_RECT_EQ(IntRect(0, 1400, 800, 8600), previousInterestRect(rootScrollingLayer));
+}
+
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/compositing/PaintLayerCompositor.cpp b/third_party/WebKit/Source/core/layout/compositing/PaintLayerCompositor.cpp
index aa46e439..9da2256 100644
--- a/third_party/WebKit/Source/core/layout/compositing/PaintLayerCompositor.cpp
+++ b/third_party/WebKit/Source/core/layout/compositing/PaintLayerCompositor.cpp
@@ -800,21 +800,19 @@
     scrollbar->paint(&context, CullRect(transformedClip));
 }
 
-void PaintLayerCompositor::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase, const IntRect* clip) const
+IntRect PaintLayerCompositor::computeInterestRect(const GraphicsLayer* graphicsLayer, const IntRect&) const
 {
-    IntRect defaultClip;
-    if (RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEnabled() && !clip) {
-        defaultClip.setSize(m_layoutView.layoutSize(IncludeScrollbars));
-        clip = &defaultClip;
-    }
-    ASSERT(clip);
+    return IntRect(IntPoint(), m_layoutView.layoutSize(IncludeScrollbars));
+}
 
+void PaintLayerCompositor::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase, const IntRect& interestRect) const
+{
     if (graphicsLayer == layerForHorizontalScrollbar())
-        paintScrollbar(m_layoutView.frameView()->horizontalScrollbar(), context, *clip);
+        paintScrollbar(m_layoutView.frameView()->horizontalScrollbar(), context, interestRect);
     else if (graphicsLayer == layerForVerticalScrollbar())
-        paintScrollbar(m_layoutView.frameView()->verticalScrollbar(), context, *clip);
+        paintScrollbar(m_layoutView.frameView()->verticalScrollbar(), context, interestRect);
     else if (graphicsLayer == layerForScrollCorner())
-        FramePainter(*m_layoutView.frameView()).paintScrollCorner(&context, *clip);
+        FramePainter(*m_layoutView.frameView()).paintScrollCorner(&context, interestRect);
 }
 
 bool PaintLayerCompositor::supportsFixedRootBackgroundCompositing() const
@@ -1184,7 +1182,7 @@
     return m_layoutView.document().lifecycle();
 }
 
-String PaintLayerCompositor::debugName(const GraphicsLayer* graphicsLayer)
+String PaintLayerCompositor::debugName(const GraphicsLayer* graphicsLayer) const
 {
     String name;
     if (graphicsLayer == m_rootContentLayer.get()) {
diff --git a/third_party/WebKit/Source/core/layout/compositing/PaintLayerCompositor.h b/third_party/WebKit/Source/core/layout/compositing/PaintLayerCompositor.h
index f4f7f60..e679e81 100644
--- a/third_party/WebKit/Source/core/layout/compositing/PaintLayerCompositor.h
+++ b/third_party/WebKit/Source/core/layout/compositing/PaintLayerCompositor.h
@@ -152,7 +152,7 @@
     void resetTrackedPaintInvalidationRects();
     void setTracksPaintInvalidations(bool);
 
-    String debugName(const GraphicsLayer*) override;
+    String debugName(const GraphicsLayer*) const override;
     DocumentLifecycle& lifecycle() const;
 
     bool needsUpdateDescendantDependentFlags() const { return m_needsUpdateDescendantDependentFlags; }
@@ -177,7 +177,8 @@
 #endif
 
     // GraphicsLayerClient implementation
-    void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect*) const override;
+    IntRect computeInterestRect(const GraphicsLayer*, const IntRect&) const override;
+    void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect& interestRect) const override;
 
     bool isTrackingPaintInvalidations() const override;
 
diff --git a/third_party/WebKit/Source/core/paint/BoxPainter.cpp b/third_party/WebKit/Source/core/paint/BoxPainter.cpp
index a4e829f..3b1f0b3 100644
--- a/third_party/WebKit/Source/core/paint/BoxPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/BoxPainter.cpp
@@ -671,7 +671,6 @@
                 else
                     influenceRect.shrinkRadii(-changeAmount);
 
-                // TODO: support non-integer shadows - crbug.com/334829
                 FloatRoundedRect roundedFillRect = border;
                 roundedFillRect.inflate(shadowSpread);
 
@@ -701,8 +700,7 @@
                 else
                     clippedEdges |= GraphicsContext::BottomEdge;
             }
-            // TODO: support non-integer shadows - crbug.com/334828
-            context->drawInnerShadow(border, shadowColor, flooredIntSize(shadowOffset), shadowBlur, shadowSpread, clippedEdges);
+            context->drawInnerShadow(border, shadowColor, shadowOffset, shadowBlur, shadowSpread, clippedEdges);
         }
     }
 }
diff --git a/third_party/WebKit/Source/core/paint/ThemePainterMac.mm b/third_party/WebKit/Source/core/paint/ThemePainterMac.mm
index 2c9ae64..681dcf65 100644
--- a/third_party/WebKit/Source/core/paint/ThemePainterMac.mm
+++ b/third_party/WebKit/Source/core/paint/ThemePainterMac.mm
@@ -347,10 +347,10 @@
     FloatRoundedRect fillRect(fillBounds, fillRadius, fillRadius, fillRadius, fillRadius);
     paintInfo.context->fillRoundedRect(fillRect, fillColor);
 
-    IntSize shadowOffset(isVerticalSlider ? 1 : 0,
-                         isVerticalSlider ? 0 : 1);
-    int shadowBlur = 3;
-    int shadowSpread = 0;
+    FloatSize shadowOffset(isVerticalSlider ? 1 : 0,
+                           isVerticalSlider ? 0 : 1);
+    float shadowBlur = 3;
+    float shadowSpread = 0;
     paintInfo.context->save();
     paintInfo.context->drawInnerShadow(fillRect, shadowColor, shadowOffset, shadowBlur, shadowSpread);
     paintInfo.context->restore();
diff --git a/third_party/WebKit/Source/core/svg/SVGURIReference.h b/third_party/WebKit/Source/core/svg/SVGURIReference.h
index 1caa06a..7174a3b 100644
--- a/third_party/WebKit/Source/core/svg/SVGURIReference.h
+++ b/third_party/WebKit/Source/core/svg/SVGURIReference.h
@@ -41,10 +41,6 @@
 
     static inline bool isExternalURIReference(const String& uri, const Document& document)
     {
-        // Fragment-only URIs are always internal
-        if (uri.startsWith('#'))
-            return false;
-
         // If the URI matches our documents URL, we're dealing with a local reference.
         KURL url = document.completeURL(uri);
         return !equalIgnoringFragmentIdentifier(url, document.url());
diff --git a/third_party/WebKit/Source/devtools/front_end/animation/AnimationControlPane.js b/third_party/WebKit/Source/devtools/front_end/animation/AnimationControlPane.js
index c6b1f76..9b48eca 100644
--- a/third_party/WebKit/Source/devtools/front_end/animation/AnimationControlPane.js
+++ b/third_party/WebKit/Source/devtools/front_end/animation/AnimationControlPane.js
@@ -110,18 +110,6 @@
     /**
      * @param {boolean} toggleOn
      */
-    _toggleAnimationTimelineMode: function(toggleOn)
-    {
-        if (!this._animationTimeline)
-            this._animationTimeline = new WebInspector.AnimationTimeline();
-        this._button.setToggled(toggleOn);
-        var elementsPanel = WebInspector.ElementsPanel.instance();
-        elementsPanel.setWidgetBelowDOM(toggleOn ? this._animationTimeline : null);
-    },
-
-    /**
-     * @param {boolean} toggleOn
-     */
     _toggleAnimationControlPaneMode: function(toggleOn)
     {
         if (!this._animationsControlPane)
@@ -132,7 +120,7 @@
     _clicked: function()
     {
         if (Runtime.experiments.isEnabled("animationInspection"))
-            this._toggleAnimationTimelineMode(!this._button.toggled());
+            WebInspector.inspectorView.showViewInDrawer("animations");
         else
             this._toggleAnimationControlPaneMode(!this._button.toggled());
     },
@@ -140,10 +128,7 @@
     _nodeChanged: function()
     {
         var node = WebInspector.context.flavor(WebInspector.DOMNode);
-        if (Runtime.experiments.isEnabled("animationInspection")) {
-            if (this._animationTimeline)
-                this._animationTimeline.setNode(node);
-        } else {
+        if (!Runtime.experiments.isEnabled("animationInspection")) {
             this._button.setEnabled(!!node);
             if (!node)
                 this._toggleAnimationControlPaneMode(false);
diff --git a/third_party/WebKit/Source/devtools/front_end/animation/AnimationTimeline.js b/third_party/WebKit/Source/devtools/front_end/animation/AnimationTimeline.js
index 8ae7d31..908e853a 100644
--- a/third_party/WebKit/Source/devtools/front_end/animation/AnimationTimeline.js
+++ b/third_party/WebKit/Source/devtools/front_end/animation/AnimationTimeline.js
@@ -91,13 +91,10 @@
         animationModel.removeEventListener(WebInspector.AnimationModel.Events.AnimationGroupStarted, this._animationGroupStarted, this);
     },
 
-    /**
-     * @param {?WebInspector.DOMNode} node
-     */
-    setNode: function(node)
+    _nodeChanged: function()
     {
         for (var nodeUI of this._nodesMap.values())
-            nodeUI.setNode(node);
+            nodeUI._nodeChanged();
     },
 
     /**
@@ -646,6 +643,7 @@
         if (!node)
             return;
         this._node = node;
+        this._nodeChanged();
         this._description.appendChild(WebInspector.DOMPresentationUtils.linkifyNodeReference(node));
     }
 
@@ -709,12 +707,9 @@
         this.element.classList.add("animation-node-removed");
     },
 
-    /**
-     * @param {?WebInspector.DOMNode} node
-     */
-    setNode: function(node)
+    _nodeChanged: function()
     {
-        this.element.classList.toggle("animation-node-selected", node === this._node);
+        this.element.classList.toggle("animation-node-selected", this._node && this._node === WebInspector.context.flavor(WebInspector.DOMNode));
     }
 }
 
diff --git a/third_party/WebKit/Source/devtools/front_end/animation/animationTimeline.css b/third_party/WebKit/Source/devtools/front_end/animation/animationTimeline.css
index aed052d7..759024e 100644
--- a/third_party/WebKit/Source/devtools/front_end/animation/animationTimeline.css
+++ b/third_party/WebKit/Source/devtools/front_end/animation/animationTimeline.css
@@ -4,6 +4,10 @@
  * found in the LICENSE file.
  */
 
+:host {
+    overflow: hidden;
+}
+
 .animation-node-row {
     width: 100%;
     display: flex;
diff --git a/third_party/WebKit/Source/devtools/front_end/animation/module.json b/third_party/WebKit/Source/devtools/front_end/animation/module.json
index 0f424268..05f4df2 100644
--- a/third_party/WebKit/Source/devtools/front_end/animation/module.json
+++ b/third_party/WebKit/Source/devtools/front_end/animation/module.json
@@ -5,6 +5,14 @@
             "className": "WebInspector.AnimationControlPane.ButtonProvider",
             "order": 2,
             "location": "styles-sidebarpane-toolbar"
+        },
+        {
+            "type": "drawer-view",
+            "name": "animations",
+            "title": "Animations",
+            "persistence": "closeable",
+            "order": 0,
+            "className": "WebInspector.AnimationTimeline"
         }
     ],
     "dependencies": [
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/ElementsPanel.js b/third_party/WebKit/Source/devtools/front_end/elements/ElementsPanel.js
index ea5bb07..647c85d 100644
--- a/third_party/WebKit/Source/devtools/front_end/elements/ElementsPanel.js
+++ b/third_party/WebKit/Source/devtools/front_end/elements/ElementsPanel.js
@@ -53,10 +53,7 @@
     stackElement.appendChild(this._contentElement);
     stackElement.appendChild(crumbsContainer);
 
-    this._treeOutlineSplit = new WebInspector.SplitWidget(false, true, "treeOutlineAnimationTimelineWidget", 300, 300);
-    this._treeOutlineSplit.hideSidebar();
-    this._treeOutlineSplit.setMainWidget(this._searchableView);
-    this._splitWidget.setMainWidget(this._treeOutlineSplit);
+    this._splitWidget.setMainWidget(this._searchableView);
 
     this._contentElement.id = "elements-content";
     // FIXME: crbug.com/425984
@@ -1057,19 +1054,6 @@
             this._extensionSidebarPanesContainer.addPane(pane);
     },
 
-    /**
-     * @param {?WebInspector.Widget} widget
-     */
-    setWidgetBelowDOM: function(widget)
-    {
-        if (widget) {
-            this._treeOutlineSplit.setSidebarWidget(widget);
-            this._treeOutlineSplit.showBoth(true);
-        } else {
-            this._treeOutlineSplit.hideSidebar(true);
-        }
-    },
-
     __proto__: WebInspector.Panel.prototype
 }
 
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/StylesSidebarPane.js b/third_party/WebKit/Source/devtools/front_end/elements/StylesSidebarPane.js
index 3d05b5a..1d6e0bea 100644
--- a/third_party/WebKit/Source/devtools/front_end/elements/StylesSidebarPane.js
+++ b/third_party/WebKit/Source/devtools/front_end/elements/StylesSidebarPane.js
@@ -921,7 +921,6 @@
         var domModel = node.domModel();
         var selectors = this._style.parentRule ? this._style.parentRule.selectorText() : undefined;
         domModel.highlightDOMNodeWithConfig(node.id, { mode: "all", showInfo: undefined, selectors: selectors });
-        this._activeHighlightDOMModel = domModel;
     },
 
     /**
diff --git a/third_party/WebKit/Source/devtools/front_end/main/Main.js b/third_party/WebKit/Source/devtools/front_end/main/Main.js
index a626ceb..6bbcc23 100644
--- a/third_party/WebKit/Source/devtools/front_end/main/Main.js
+++ b/third_party/WebKit/Source/devtools/front_end/main/Main.js
@@ -147,6 +147,7 @@
         }
 
         Runtime.experiments.setDefaultExperiments([
+            "animationInspection",
             "deviceMode",
             "securityPanel"
         ]);
diff --git a/third_party/WebKit/Source/modules/background_sync/SyncCallbacks.cpp b/third_party/WebKit/Source/modules/background_sync/SyncCallbacks.cpp
index c0cd78e..9f31ab1 100644
--- a/third_party/WebKit/Source/modules/background_sync/SyncCallbacks.cpp
+++ b/third_party/WebKit/Source/modules/background_sync/SyncCallbacks.cpp
@@ -120,20 +120,14 @@
 
 void SyncGetRegistrationsCallbacks::onSuccess(const WebVector<WebSyncRegistration*>& webSyncRegistrations)
 {
-    Vector<OwnPtr<WebSyncRegistration>> registrations;
-    for (WebSyncRegistration* r : webSyncRegistrations) {
-        registrations.append(adoptPtr(r));
-    }
     if (!m_resolver->executionContext() || m_resolver->executionContext()->activeDOMObjectsAreStopped()) {
         return;
     }
-
-    HeapVector<Member<SyncRegistration>> syncRegistrations;
-    for (auto& r : registrations) {
-        SyncRegistration* reg = SyncRegistration::take(m_resolver.get(), r.release(), m_serviceWorkerRegistration);
-        syncRegistrations.append(reg);
+    Vector<String> tags;
+    for (const WebSyncRegistration* r : webSyncRegistrations) {
+        tags.append(r->tag);
     }
-    m_resolver->resolve(syncRegistrations);
+    m_resolver->resolve(tags);
 }
 
 void SyncGetRegistrationsCallbacks::onError(const WebSyncError& error)
diff --git a/third_party/WebKit/Source/modules/background_sync/SyncEvent.cpp b/third_party/WebKit/Source/modules/background_sync/SyncEvent.cpp
index b109a111..c4f7906 100644
--- a/third_party/WebKit/Source/modules/background_sync/SyncEvent.cpp
+++ b/third_party/WebKit/Source/modules/background_sync/SyncEvent.cpp
@@ -11,9 +11,9 @@
 {
 }
 
-SyncEvent::SyncEvent(const AtomicString& type, SyncRegistration* syncRegistration, bool lastChance, WaitUntilObserver* observer)
+SyncEvent::SyncEvent(const AtomicString& type, const String& tag, bool lastChance, WaitUntilObserver* observer)
     : ExtendableEvent(type, ExtendableEventInit(), observer)
-    , m_syncRegistration(syncRegistration)
+    , m_tag(tag)
     , m_lastChance(lastChance)
 {
 }
@@ -21,7 +21,7 @@
 SyncEvent::SyncEvent(const AtomicString& type, const SyncEventInit& init)
     : ExtendableEvent(type, init)
 {
-    m_syncRegistration = init.registration();
+    m_tag = init.tag();
     m_lastChance = init.lastChance();
 }
 
@@ -34,9 +34,9 @@
     return EventNames::SyncEvent;
 }
 
-SyncRegistration* SyncEvent::registration()
+String SyncEvent::tag()
 {
-    return m_syncRegistration.get();
+    return m_tag;
 }
 
 bool SyncEvent::lastChance()
@@ -46,7 +46,6 @@
 
 DEFINE_TRACE(SyncEvent)
 {
-    visitor->trace(m_syncRegistration);
     ExtendableEvent::trace(visitor);
 }
 
diff --git a/third_party/WebKit/Source/modules/background_sync/SyncEvent.h b/third_party/WebKit/Source/modules/background_sync/SyncEvent.h
index d5b8665..5b969a5 100644
--- a/third_party/WebKit/Source/modules/background_sync/SyncEvent.h
+++ b/third_party/WebKit/Source/modules/background_sync/SyncEvent.h
@@ -22,9 +22,9 @@
     {
         return adoptRefWillBeNoop(new SyncEvent);
     }
-    static PassRefPtrWillBeRawPtr<SyncEvent> create(const AtomicString& type, SyncRegistration* syncRegistration, bool lastChance, WaitUntilObserver* observer)
+    static PassRefPtrWillBeRawPtr<SyncEvent> create(const AtomicString& type, const String& tag, bool lastChance, WaitUntilObserver* observer)
     {
-        return adoptRefWillBeNoop(new SyncEvent(type, syncRegistration, lastChance, observer));
+        return adoptRefWillBeNoop(new SyncEvent(type, tag, lastChance, observer));
     }
     static PassRefPtrWillBeRawPtr<SyncEvent> create(const AtomicString& type, const SyncEventInit& init)
     {
@@ -35,17 +35,17 @@
 
     const AtomicString& interfaceName() const override;
 
-    SyncRegistration* registration();
+    String tag();
     bool lastChance();
 
     DECLARE_VIRTUAL_TRACE();
 
 private:
     SyncEvent();
-    SyncEvent(const AtomicString& type, SyncRegistration*, bool, WaitUntilObserver*);
+    SyncEvent(const AtomicString& type, const String&, bool, WaitUntilObserver*);
     SyncEvent(const AtomicString& type, const SyncEventInit&);
 
-    PersistentWillBeMember<SyncRegistration> m_syncRegistration;
+    String m_tag;
     bool m_lastChance;
 };
 
diff --git a/third_party/WebKit/Source/modules/background_sync/SyncEvent.idl b/third_party/WebKit/Source/modules/background_sync/SyncEvent.idl
index f828e499..f663de05 100644
--- a/third_party/WebKit/Source/modules/background_sync/SyncEvent.idl
+++ b/third_party/WebKit/Source/modules/background_sync/SyncEvent.idl
@@ -7,6 +7,6 @@
     Exposed=ServiceWorker,
     RuntimeEnabled=BackgroundSync,
 ] interface SyncEvent : ExtendableEvent {
-    readonly attribute SyncRegistration registration;
+    readonly attribute DOMString tag;
     readonly attribute boolean lastChance;
 };
diff --git a/third_party/WebKit/Source/modules/background_sync/SyncEventInit.idl b/third_party/WebKit/Source/modules/background_sync/SyncEventInit.idl
index df44f64..1a2a8049 100644
--- a/third_party/WebKit/Source/modules/background_sync/SyncEventInit.idl
+++ b/third_party/WebKit/Source/modules/background_sync/SyncEventInit.idl
@@ -3,6 +3,6 @@
 // found in the LICENSE file.
 
 dictionary SyncEventInit : ExtendableEventInit {
-    required SyncRegistration registration;
-    required boolean lastChance;
+    required DOMString tag;
+    boolean lastChance = false;
 };
diff --git a/third_party/WebKit/Source/modules/background_sync/SyncManager.cpp b/third_party/WebKit/Source/modules/background_sync/SyncManager.cpp
index dae56c1ee..4593672 100644
--- a/third_party/WebKit/Source/modules/background_sync/SyncManager.cpp
+++ b/third_party/WebKit/Source/modules/background_sync/SyncManager.cpp
@@ -40,7 +40,7 @@
     ASSERT(registration);
 }
 
-ScriptPromise SyncManager::registerFunction(ScriptState* scriptState, ExecutionContext* context, const SyncRegistrationOptions& options)
+ScriptPromise SyncManager::registerFunction(ScriptState* scriptState, ExecutionContext* context, const String& tag)
 {
     // TODO(jkarlin): Wait for the registration to become active instead of rejecting. See crbug.com/542437.
     if (!m_registration->active())
@@ -52,7 +52,7 @@
     WebSyncRegistration* webSyncRegistration = new WebSyncRegistration(
         WebSyncRegistration::UNREGISTERED_SYNC_ID /* id */,
         WebSyncRegistration::PeriodicityOneShot,
-        options.tag(),
+        tag,
         0 /* minPeriod */,
         WebSyncRegistration::NetworkStateOnline /* networkState */,
         WebSyncRegistration::PowerStateAuto /* powerState */
@@ -62,17 +62,7 @@
     return promise;
 }
 
-ScriptPromise SyncManager::getRegistration(ScriptState* scriptState, const String& syncRegistrationId)
-{
-    ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
-    ScriptPromise promise = resolver->promise();
-
-    backgroundSyncProvider()->getRegistration(WebSyncRegistration::PeriodicityOneShot, syncRegistrationId, m_registration->webRegistration(), new SyncRegistrationCallbacks(resolver, m_registration));
-
-    return promise;
-}
-
-ScriptPromise SyncManager::getRegistrations(ScriptState* scriptState)
+ScriptPromise SyncManager::getTags(ScriptState* scriptState)
 {
     ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
     ScriptPromise promise = resolver->promise();
@@ -82,16 +72,6 @@
     return promise;
 }
 
-ScriptPromise SyncManager::permissionState(ScriptState* scriptState)
-{
-    ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
-    ScriptPromise promise = resolver->promise();
-
-    backgroundSyncProvider()->getPermissionStatus(WebSyncRegistration::PeriodicityOneShot, m_registration->webRegistration(), new SyncGetPermissionStatusCallbacks(resolver, m_registration));
-
-    return promise;
-}
-
 DEFINE_TRACE(SyncManager)
 {
     visitor->trace(m_registration);
diff --git a/third_party/WebKit/Source/modules/background_sync/SyncManager.h b/third_party/WebKit/Source/modules/background_sync/SyncManager.h
index 8690788f..2529574 100644
--- a/third_party/WebKit/Source/modules/background_sync/SyncManager.h
+++ b/third_party/WebKit/Source/modules/background_sync/SyncManager.h
@@ -27,10 +27,8 @@
 
     unsigned long minAllowablePeriod();
 
-    ScriptPromise registerFunction(ScriptState*, ExecutionContext*, const SyncRegistrationOptions&);
-    ScriptPromise getRegistration(ScriptState*, const String&);
-    ScriptPromise getRegistrations(ScriptState*);
-    ScriptPromise permissionState(ScriptState*);
+    ScriptPromise registerFunction(ScriptState*, ExecutionContext*, const String&);
+    ScriptPromise getTags(ScriptState*);
 
     DECLARE_TRACE();
 
diff --git a/third_party/WebKit/Source/modules/background_sync/SyncManager.idl b/third_party/WebKit/Source/modules/background_sync/SyncManager.idl
index 30f3ada..de186a1 100644
--- a/third_party/WebKit/Source/modules/background_sync/SyncManager.idl
+++ b/third_party/WebKit/Source/modules/background_sync/SyncManager.idl
@@ -14,8 +14,6 @@
     RuntimeEnabled=BackgroundSync,
     TypeChecking=Interface,
 ] interface SyncManager {
-    [CallWith=(ScriptState,ExecutionContext),ImplementedAs=registerFunction] Promise<SyncRegistration> register([RuntimeEnabled=BackgroundSyncV2] optional SyncRegistrationOptions options);
-    [CallWith=ScriptState] Promise<SyncRegistration> getRegistration(DOMString tag);
-    [CallWith=ScriptState] Promise<sequence<SyncRegistration>> getRegistrations();
-    [RuntimeEnabled=BackgroundSyncV2, CallWith=ScriptState] Promise<SyncPermissionState> permissionState();
+    [MeasureAs=BackgroundSyncRegister,CallWith=(ScriptState,ExecutionContext),ImplementedAs=registerFunction] Promise<void> register(DOMString tag);
+    [CallWith=ScriptState] Promise<sequence<DOMString>> getTags();
 };
diff --git a/third_party/WebKit/Source/modules/background_sync/SyncRegistration.idl b/third_party/WebKit/Source/modules/background_sync/SyncRegistration.idl
index add356ea..ccc69db8 100644
--- a/third_party/WebKit/Source/modules/background_sync/SyncRegistration.idl
+++ b/third_party/WebKit/Source/modules/background_sync/SyncRegistration.idl
@@ -3,8 +3,8 @@
 // found in the LICENSE file.
 
 [
-    Exposed=(Window,ServiceWorker),
     GarbageCollected,
+    NoInterfaceObject,
     RuntimeEnabled=BackgroundSync,
 ] interface SyncRegistration {
     readonly attribute DOMString tag;
diff --git a/third_party/WebKit/Source/platform/fonts/Character.cpp b/third_party/WebKit/Source/platform/fonts/Character.cpp
index ea33001a..5ea155b 100644
--- a/third_party/WebKit/Source/platform/fonts/Character.cpp
+++ b/third_party/WebKit/Source/platform/fonts/Character.cpp
@@ -148,6 +148,14 @@
             if (supplementaryCharacter <= 0x1F1FF)
                 return ComplexPath;
 
+            // Man and Woman Emojies,
+            // in order to support emoji joiner combinations for family and couple pictographs.
+            // Compare http://unicode.org/reports/tr51/#Emoji_ZWJ_Sequences
+            if (supplementaryCharacter < 0x1F468)
+                continue;
+            if (supplementaryCharacter <= 0x1F469)
+                return ComplexPath;
+
             if (supplementaryCharacter < 0xE0100) // U+E0100 through U+E01EF Unicode variation selectors.
                 continue;
             if (supplementaryCharacter <= 0xE01EF)
diff --git a/third_party/WebKit/Source/platform/fonts/Character.h b/third_party/WebKit/Source/platform/fonts/Character.h
index bb6ef77c..f14fa08 100644
--- a/third_party/WebKit/Source/platform/fonts/Character.h
+++ b/third_party/WebKit/Source/platform/fonts/Character.h
@@ -93,6 +93,11 @@
     }
     static bool canReceiveTextEmphasis(UChar32);
 
+    static bool isModifier(UChar32 c)
+    {
+        return c >= 0x1F3FB && c <= 0x1F3FF;
+    }
+
     static inline UChar normalizeSpaces(UChar character)
     {
         if (treatAsSpace(character))
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaper.cpp b/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaper.cpp
index 0678568..3934ccb 100644
--- a/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaper.cpp
+++ b/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaper.cpp
@@ -107,6 +107,8 @@
             character = spaceCharacter;
         else if (Character::treatAsZeroWidthSpaceInComplexScript(character))
             character = zeroWidthSpaceCharacter;
+        else if (Character::isModifier(character))
+            character = zeroWidthSpaceCharacter;
 
         U16_APPEND(destination, *destinationLength, length, character, error);
         ASSERT_UNUSED(error, !error);
diff --git a/third_party/WebKit/Source/platform/graphics/ContentLayerDelegate.h b/third_party/WebKit/Source/platform/graphics/ContentLayerDelegate.h
index 6403762..e07ce0d 100644
--- a/third_party/WebKit/Source/platform/graphics/ContentLayerDelegate.h
+++ b/third_party/WebKit/Source/platform/graphics/ContentLayerDelegate.h
@@ -41,7 +41,7 @@
 
 class PLATFORM_EXPORT GraphicsContextPainter {
 public:
-    virtual void paint(GraphicsContext&, const IntRect* clip) = 0;
+    virtual void paint(GraphicsContext&, const IntRect* interestRect) = 0;
     virtual PaintController* paintController() = 0;
 
 protected:
diff --git a/third_party/WebKit/Source/platform/graphics/DrawLooperBuilder.cpp b/third_party/WebKit/Source/platform/graphics/DrawLooperBuilder.cpp
index fc1c648..7c16dc9a 100644
--- a/third_party/WebKit/Source/platform/graphics/DrawLooperBuilder.cpp
+++ b/third_party/WebKit/Source/platform/graphics/DrawLooperBuilder.cpp
@@ -67,9 +67,7 @@
 void DrawLooperBuilder::addShadow(const FloatSize& offset, float blur, const Color& color,
     ShadowTransformMode shadowTransformMode, ShadowAlphaMode shadowAlphaMode)
 {
-    // Negative blurs are not allowed, so just pin the value to 0
-    if (blur < 0)
-        blur = 0;
+    ASSERT(blur >= 0);
 
     // Detect when there's no effective shadow.
     if (!color.alpha())
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsContext.cpp b/third_party/WebKit/Source/platform/graphics/GraphicsContext.cpp
index 18eb9a03..ec3f157 100644
--- a/third_party/WebKit/Source/platform/graphics/GraphicsContext.cpp
+++ b/third_party/WebKit/Source/platform/graphics/GraphicsContext.cpp
@@ -31,6 +31,7 @@
 #include "platform/geometry/IntRect.h"
 #include "platform/graphics/ColorSpace.h"
 #include "platform/graphics/Gradient.h"
+#include "platform/graphics/GraphicsContextStateSaver.h"
 #include "platform/graphics/ImageBuffer.h"
 #include "platform/graphics/paint/PaintController.h"
 #include "platform/weborigin/KURL.h"
@@ -412,21 +413,23 @@
     }
 }
 
-static inline FloatRect areaCastingShadowInHole(const FloatRect& holeRect, int shadowBlur, int shadowSpread, const IntSize& shadowOffset)
+static inline FloatRect areaCastingShadowInHole(const FloatRect& holeRect, float shadowBlur,
+    float shadowSpread, const FloatSize& shadowOffset)
 {
-    IntRect bounds(holeRect);
+    FloatRect bounds(holeRect);
 
     bounds.inflate(shadowBlur);
 
     if (shadowSpread < 0)
         bounds.inflate(-shadowSpread);
 
-    IntRect offsetBounds = bounds;
+    FloatRect offsetBounds = bounds;
     offsetBounds.move(-shadowOffset);
     return unionRect(bounds, offsetBounds);
 }
 
-void GraphicsContext::drawInnerShadow(const FloatRoundedRect& rect, const Color& shadowColor, const IntSize shadowOffset, int shadowBlur, int shadowSpread, Edges clippedEdges)
+void GraphicsContext::drawInnerShadow(const FloatRoundedRect& rect, const Color& shadowColor,
+    const FloatSize& shadowOffset, float shadowBlur, float shadowSpread, Edges clippedEdges)
 {
     if (contextDisabled())
         return;
@@ -440,24 +443,24 @@
     }
 
     if (clippedEdges & LeftEdge) {
-        holeRect.move(-std::max(shadowOffset.width(), 0) - shadowBlur, 0);
-        holeRect.setWidth(holeRect.width() + std::max(shadowOffset.width(), 0) + shadowBlur);
+        holeRect.move(-std::max(shadowOffset.width(), 0.0f) - shadowBlur, 0);
+        holeRect.setWidth(holeRect.width() + std::max(shadowOffset.width(), 0.0f) + shadowBlur);
     }
     if (clippedEdges & TopEdge) {
-        holeRect.move(0, -std::max(shadowOffset.height(), 0) - shadowBlur);
-        holeRect.setHeight(holeRect.height() + std::max(shadowOffset.height(), 0) + shadowBlur);
+        holeRect.move(0, -std::max(shadowOffset.height(), 0.0f) - shadowBlur);
+        holeRect.setHeight(holeRect.height() + std::max(shadowOffset.height(), 0.0f) + shadowBlur);
     }
     if (clippedEdges & RightEdge)
-        holeRect.setWidth(holeRect.width() - std::min(shadowOffset.width(), 0) + shadowBlur);
+        holeRect.setWidth(holeRect.width() - std::min(shadowOffset.width(), 0.0f) + shadowBlur);
     if (clippedEdges & BottomEdge)
-        holeRect.setHeight(holeRect.height() - std::min(shadowOffset.height(), 0) + shadowBlur);
+        holeRect.setHeight(holeRect.height() - std::min(shadowOffset.height(), 0.0f) + shadowBlur);
 
     Color fillColor(shadowColor.red(), shadowColor.green(), shadowColor.blue(), 255);
 
     FloatRect outerRect = areaCastingShadowInHole(rect.rect(), shadowBlur, shadowSpread, shadowOffset);
     FloatRoundedRect roundedHole(holeRect, rect.radii());
 
-    save();
+    GraphicsContextStateSaver stateSaver(*this);
     if (rect.isRounded()) {
         clipRoundedRect(rect);
         if (shadowSpread < 0)
@@ -473,8 +476,6 @@
         DrawLooperBuilder::ShadowRespectsTransforms, DrawLooperBuilder::ShadowIgnoresAlpha);
     setDrawLooper(drawLooperBuilder.release());
     fillRectWithRoundedHole(outerRect, roundedHole, fillColor);
-    restore();
-    clearDrawLooper();
 }
 
 void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2)
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsContext.h b/third_party/WebKit/Source/platform/graphics/GraphicsContext.h
index be487e63..c700e6d 100644
--- a/third_party/WebKit/Source/platform/graphics/GraphicsContext.h
+++ b/third_party/WebKit/Source/platform/graphics/GraphicsContext.h
@@ -231,7 +231,9 @@
         LeftEdge = 1 << 4
     };
     typedef unsigned Edges;
-    void drawInnerShadow(const FloatRoundedRect&, const Color& shadowColor, const IntSize shadowOffset, int shadowBlur, int shadowSpread, Edges clippedEdges = NoEdge);
+    void drawInnerShadow(const FloatRoundedRect&, const Color& shadowColor,
+        const FloatSize& shadowOffset, float shadowBlur, float shadowSpread,
+        Edges clippedEdges = NoEdge);
 
     const SkPaint& fillPaint() const { return immutableState()->fillPaint(); }
 
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp
index 4d51cb8a..6dadd470 100644
--- a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp
+++ b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp
@@ -293,9 +293,9 @@
         setNeedsDisplay();
 }
 
-void GraphicsLayer::paint(GraphicsContext& context, const IntRect* clip)
+void GraphicsLayer::paint(GraphicsContext& context, const IntRect* interestRect)
 {
-    ASSERT(clip || RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEnabled());
+    ASSERT(interestRect || RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEnabled());
     ASSERT(drawsContent());
 
     if (!m_client)
@@ -312,8 +312,22 @@
         }
     }
 #endif
-    m_client->paintContents(this, context, m_paintingPhase, clip);
+
+    IntRect newInterestRect;
+    if (RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEnabled()) {
+        if (!interestRect) {
+            newInterestRect = m_client->computeInterestRect(this, m_previousInterestRect);
+            interestRect = &newInterestRect;
+        }
+        if (!m_client->needsRepaint() && !paintController()->cacheIsEmpty() && m_previousInterestRect == *interestRect) {
+            paintController()->createAndAppend<CachedDisplayItem>(*this, DisplayItem::CachedDisplayItemList);
+            return;
+        }
+    }
+
+    m_client->paintContents(this, context, m_paintingPhase, *interestRect);
     notifyFirstPaintToClient();
+    m_previousInterestRect = *interestRect;
 }
 
 void GraphicsLayer::notifyFirstPaintToClient()
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.h b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.h
index 48105ff..6e58663 100644
--- a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.h
+++ b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.h
@@ -246,7 +246,7 @@
     static void unregisterContentsLayer(WebLayer*);
 
     // GraphicsContextPainter implementation.
-    void paint(GraphicsContext&, const IntRect* clip) override;
+    void paint(GraphicsContext&, const IntRect* interestRect) override;
 
     // WebCompositorAnimationDelegate implementation.
     void notifyAnimationStarted(double monotonicTime, int group) override;
@@ -263,10 +263,8 @@
     static void setDrawDebugRedFillForTesting(bool);
     ContentLayerDelegate* contentLayerDelegateForTesting() const { return m_contentLayerDelegate.get(); }
 
-#ifndef NDEBUG
     DisplayItemClient displayItemClient() const { return toDisplayItemClient(this); }
-    String debugName() const { return m_client->debugName(this) + " debug red fill"; }
-#endif
+    String debugName() const { return m_client->debugName(this); }
 
 protected:
     String debugName(WebLayer*) const;
@@ -275,6 +273,7 @@
     // GraphicsLayerFactoryChromium that wants to create a GraphicsLayer need to be friends.
     friend class GraphicsLayerFactoryChromium;
     // for testing
+    friend class CompositedLayerMappingTest;
     friend class FakeGraphicsLayerFactory;
 
 private:
@@ -374,6 +373,8 @@
     int m_3dRenderingContext;
 
     OwnPtr<PaintController> m_paintController;
+
+    IntRect m_previousInterestRect;
 };
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsLayerClient.h b/third_party/WebKit/Source/platform/graphics/GraphicsLayerClient.h
index e2406d5..6959096b3 100644
--- a/third_party/WebKit/Source/platform/graphics/GraphicsLayerClient.h
+++ b/third_party/WebKit/Source/platform/graphics/GraphicsLayerClient.h
@@ -69,10 +69,13 @@
     virtual void notifyFirstTextPaint() { }
     virtual void notifyFirstImagePaint() { }
 
-    virtual void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect* inClip) const = 0;
+    virtual IntRect computeInterestRect(const GraphicsLayer*, const IntRect& previousInterestRect) const = 0;
+    virtual bool needsRepaint() const { return true; }
+    virtual void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect& interestRect) const = 0;
+
     virtual bool isTrackingPaintInvalidations() const { return false; }
 
-    virtual String debugName(const GraphicsLayer*) = 0;
+    virtual String debugName(const GraphicsLayer*) const = 0;
 
 #if ENABLE(ASSERT)
     // CompositedLayerMapping overrides this to verify that it is not
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsLayerTest.cpp b/third_party/WebKit/Source/platform/graphics/GraphicsLayerTest.cpp
index 756bf7d0..8123bc2c 100644
--- a/third_party/WebKit/Source/platform/graphics/GraphicsLayerTest.cpp
+++ b/third_party/WebKit/Source/platform/graphics/GraphicsLayerTest.cpp
@@ -49,8 +49,9 @@
 
 class MockGraphicsLayerClient : public GraphicsLayerClient {
 public:
-    void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect* inClip) const override { }
-    String debugName(const GraphicsLayer*) override { return String(); }
+    IntRect computeInterestRect(const GraphicsLayer*, const IntRect&) const { return IntRect(); }
+    void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect&) const override { }
+    String debugName(const GraphicsLayer*) const override { return String(); }
 };
 
 class GraphicsLayerForTesting : public GraphicsLayer {
diff --git a/third_party/WebKit/Source/platform/graphics/ImageLayerChromiumTest.cpp b/third_party/WebKit/Source/platform/graphics/ImageLayerChromiumTest.cpp
index f742a96..61f05d9a 100644
--- a/third_party/WebKit/Source/platform/graphics/ImageLayerChromiumTest.cpp
+++ b/third_party/WebKit/Source/platform/graphics/ImageLayerChromiumTest.cpp
@@ -37,9 +37,9 @@
 
 class MockGraphicsLayerClient : public GraphicsLayerClient {
 public:
-    void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect*) const override { }
-
-    String debugName(const GraphicsLayer*) override { return String(); }
+    IntRect computeInterestRect(const GraphicsLayer*, const IntRect&) const { return IntRect(); }
+    void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect&) const override { }
+    String debugName(const GraphicsLayer*) const override { return String(); }
 };
 
 class TestImage : public Image {
diff --git a/third_party/WebKit/Source/web/InspectorOverlay.cpp b/third_party/WebKit/Source/web/InspectorOverlay.cpp
index 5d9c444..6aac655 100644
--- a/third_party/WebKit/Source/web/InspectorOverlay.cpp
+++ b/third_party/WebKit/Source/web/InspectorOverlay.cpp
@@ -411,8 +411,11 @@
     String selectors = m_nodeHighlightConfig.selectorList;
     RefPtrWillBeRawPtr<StaticElementList> elements = nullptr;
     TrackExceptionState exceptionState;
+    ContainerNode* queryBase = m_highlightNode->containingShadowRoot();
+    if (!queryBase)
+        queryBase = m_highlightNode->ownerDocument();
     if (selectors.length())
-        elements = m_highlightNode->ownerDocument()->querySelectorAll(AtomicString(selectors), exceptionState);
+        elements = queryBase->querySelectorAll(AtomicString(selectors), exceptionState);
     if (elements && !exceptionState.hadException()) {
         for (unsigned i = 0; i < elements->length(); ++i) {
             Element* element = elements->item(i);
diff --git a/third_party/WebKit/Source/web/PageOverlay.cpp b/third_party/WebKit/Source/web/PageOverlay.cpp
index 86ae847..cf837ab 100644
--- a/third_party/WebKit/Source/web/PageOverlay.cpp
+++ b/third_party/WebKit/Source/web/PageOverlay.cpp
@@ -96,13 +96,18 @@
     m_layer->setNeedsDisplay();
 }
 
-void PageOverlay::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& gc, GraphicsLayerPaintingPhase phase, const IntRect* inClip) const
+IntRect PageOverlay::computeInterestRect(const GraphicsLayer* graphicsLayer, const IntRect&) const
 {
-    ASSERT(m_layer);
-    m_delegate->paintPageOverlay(*this, gc, expandedIntSize(m_layer->size()));
+    return IntRect(IntPoint(), expandedIntSize(m_layer->size()));
 }
 
-String PageOverlay::debugName(const GraphicsLayer*)
+void PageOverlay::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& gc, GraphicsLayerPaintingPhase phase, const IntRect& interestRect) const
+{
+    ASSERT(m_layer);
+    m_delegate->paintPageOverlay(*this, gc, interestRect.size());
+}
+
+String PageOverlay::debugName(const GraphicsLayer*) const
 {
     return "WebViewImpl Page Overlay Content Layer";
 }
diff --git a/third_party/WebKit/Source/web/PageOverlay.h b/third_party/WebKit/Source/web/PageOverlay.h
index 305fe2d..87f772f 100644
--- a/third_party/WebKit/Source/web/PageOverlay.h
+++ b/third_party/WebKit/Source/web/PageOverlay.h
@@ -69,8 +69,9 @@
     String debugName() const { return "PageOverlay"; }
 
     // GraphicsLayerClient implementation
-    void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect* inClip) const override;
-    String debugName(const GraphicsLayer*) override;
+    IntRect computeInterestRect(const GraphicsLayer*, const IntRect&) const override;
+    void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect& interestRect) const override;
+    String debugName(const GraphicsLayer*) const override;
 
 private:
     PageOverlay(WebViewImpl*, PageOverlay::Delegate*);
diff --git a/third_party/WebKit/Source/web/ServiceWorkerGlobalScopeProxy.cpp b/third_party/WebKit/Source/web/ServiceWorkerGlobalScopeProxy.cpp
index 3a311b1..fbf8875a 100644
--- a/third_party/WebKit/Source/web/ServiceWorkerGlobalScopeProxy.cpp
+++ b/third_party/WebKit/Source/web/ServiceWorkerGlobalScopeProxy.cpp
@@ -61,6 +61,7 @@
 #include "modules/serviceworkers/WaitUntilObserver.h"
 #include "platform/RuntimeEnabledFeatures.h"
 #include "public/platform/WebCrossOriginServiceWorkerClient.h"
+#include "public/platform/modules/background_sync/WebSyncRegistration.h"
 #include "public/platform/modules/notifications/WebNotificationData.h"
 #include "public/platform/modules/serviceworker/WebServiceWorkerEventResult.h"
 #include "public/platform/modules/serviceworker/WebServiceWorkerRequest.h"
@@ -177,7 +178,7 @@
         return;
     }
     WaitUntilObserver* observer = WaitUntilObserver::create(m_workerGlobalScope, WaitUntilObserver::Sync, eventID);
-    RefPtrWillBeRawPtr<Event> event(SyncEvent::create(EventTypeNames::sync, SyncRegistration::create(registration, m_workerGlobalScope->registration()), lastChance == IsLastChance, observer));
+    RefPtrWillBeRawPtr<Event> event(SyncEvent::create(EventTypeNames::sync, registration.tag, lastChance == IsLastChance, observer));
     m_workerGlobalScope->dispatchExtendableEvent(event.release(), observer);
 }
 
diff --git a/third_party/WebKit/Source/web/WebDOMResourceProgressEvent.cpp b/third_party/WebKit/Source/web/WebDOMResourceProgressEvent.cpp
deleted file mode 100644
index 6720fae..0000000
--- a/third_party/WebKit/Source/web/WebDOMResourceProgressEvent.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "public/web/WebDOMResourceProgressEvent.h"
-
-#include "core/events/ResourceProgressEvent.h"
-#include "public/platform/WebString.h"
-
-namespace blink {
-
-WebDOMResourceProgressEvent::WebDOMResourceProgressEvent(const WebString& type, bool lengthIsComputable, unsigned long long loaded, unsigned long long total, const WebString& url)
-    : WebDOMProgressEvent()
-{
-    assign(ResourceProgressEvent::create(type, lengthIsComputable, loaded, total, url));
-}
-
-} // namespace blink
diff --git a/third_party/WebKit/Source/web/WebElement.cpp b/third_party/WebKit/Source/web/WebElement.cpp
index 6888f61..0fada19a 100644
--- a/third_party/WebKit/Source/web/WebElement.cpp
+++ b/third_party/WebKit/Source/web/WebElement.cpp
@@ -94,14 +94,6 @@
     return constUnwrap<Element>()->hasAttribute(attrName);
 }
 
-void WebElement::removeAttribute(const WebString& attrName)
-{
-    // TODO: Custom element callbacks need to be called on WebKit API methods that
-    // mutate the DOM in any way.
-    CustomElementProcessingStack::CallbackDeliveryScope deliverCustomElementCallbacks;
-    unwrap<Element>()->removeAttribute(attrName);
-}
-
 WebString WebElement::getAttribute(const WebString& attrName) const
 {
     return constUnwrap<Element>()->getAttribute(attrName);
diff --git a/third_party/WebKit/Source/web/WebImageCache.cpp b/third_party/WebKit/Source/web/WebImageCache.cpp
index 8648b1e2..0e22c37 100644
--- a/third_party/WebKit/Source/web/WebImageCache.cpp
+++ b/third_party/WebKit/Source/web/WebImageCache.cpp
@@ -35,24 +35,9 @@
 
 namespace blink {
 
-void WebImageCache::setCacheLimitInBytes(size_t size)
-{
-    ImageDecodingStore::instance().setCacheLimitInBytes(size);
-}
-
 void WebImageCache::clear()
 {
     ImageDecodingStore::instance().clear();
 }
 
-size_t WebImageCache::memoryUsageInBytes()
-{
-    return ImageDecodingStore::instance().memoryUsageInBytes();
-}
-
-unsigned WebImageCache::cacheEntries()
-{
-    return ImageDecodingStore::instance().cacheEntries();
-}
-
 }  // namespace blink
diff --git a/third_party/WebKit/Source/web/WebOptionElement.cpp b/third_party/WebKit/Source/web/WebOptionElement.cpp
index e1c03d5..2d6e97eb 100644
--- a/third_party/WebKit/Source/web/WebOptionElement.cpp
+++ b/third_party/WebKit/Source/web/WebOptionElement.cpp
@@ -33,27 +33,16 @@
 
 #include "core/HTMLNames.h"
 #include "core/html/HTMLOptionElement.h"
-#include "core/html/HTMLSelectElement.h"
 #include "public/platform/WebString.h"
 #include "wtf/PassRefPtr.h"
 
 namespace blink {
 
-void WebOptionElement::setValue(const WebString& newValue)
-{
-    unwrap<HTMLOptionElement>()->setValue(newValue);
-}
-
 WebString WebOptionElement::value() const
 {
     return constUnwrap<HTMLOptionElement>()->value();
 }
 
-int WebOptionElement::index() const
-{
-    return constUnwrap<HTMLOptionElement>()->index();
-}
-
 WebString WebOptionElement::text() const
 {
     return constUnwrap<HTMLOptionElement>()->displayLabel();
@@ -64,11 +53,6 @@
     return constUnwrap<HTMLOptionElement>()->label();
 }
 
-bool WebOptionElement::isEnabled() const
-{
-    return !(constUnwrap<HTMLOptionElement>()->isDisabledFormControl());
-}
-
 WebOptionElement::WebOptionElement(const PassRefPtrWillBeRawPtr<HTMLOptionElement>& elem)
     : WebElement(elem)
 {
diff --git a/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp b/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp
index 60ab35cf..6c4a2be 100644
--- a/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp
+++ b/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp
@@ -43,6 +43,8 @@
 #include "core/events/GestureEvent.h"
 #include "core/events/KeyboardEvent.h"
 #include "core/events/MouseEvent.h"
+#include "core/events/ProgressEvent.h"
+#include "core/events/ResourceProgressEvent.h"
 #include "core/events/TouchEvent.h"
 #include "core/events/WheelEvent.h"
 #include "core/frame/EventHandlerRegistry.h"
@@ -391,6 +393,17 @@
     return WebElement(m_element);
 }
 
+void WebPluginContainerImpl::dispatchProgressEvent(const WebString& type, bool lengthComputable, unsigned long long loaded, unsigned long long total, const WebString& url)
+{
+    RefPtrWillBeRawPtr<ProgressEvent> event;
+    if (url.isEmpty()) {
+        event = ProgressEvent::create(type, lengthComputable, loaded, total);
+    } else {
+        event = ResourceProgressEvent::create(type, lengthComputable, loaded, total, url);
+    }
+    m_element->dispatchEvent(event.release());
+}
+
 void WebPluginContainerImpl::invalidate()
 {
     Widget::invalidate();
diff --git a/third_party/WebKit/Source/web/WebPluginContainerImpl.h b/third_party/WebKit/Source/web/WebPluginContainerImpl.h
index dad54db..d0be624 100644
--- a/third_party/WebKit/Source/web/WebPluginContainerImpl.h
+++ b/third_party/WebKit/Source/web/WebPluginContainerImpl.h
@@ -97,6 +97,7 @@
 
     // WebPluginContainer methods
     WebElement element() override;
+    void dispatchProgressEvent(const WebString& type, bool lengthComputable, unsigned long long loaded, unsigned long long total, const WebString& url) override;
     void invalidate() override;
     void invalidateRect(const WebRect&) override;
     void scrollRect(const WebRect&) override;
diff --git a/third_party/WebKit/Source/web/web.gypi b/third_party/WebKit/Source/web/web.gypi
index 023ed7ac..ea6eaaa1 100644
--- a/third_party/WebKit/Source/web/web.gypi
+++ b/third_party/WebKit/Source/web/web.gypi
@@ -123,7 +123,6 @@
       'WebDOMMediaStreamTrack.cpp',
       'WebDOMMessageEvent.cpp',
       'WebDOMProgressEvent.cpp',
-      'WebDOMResourceProgressEvent.cpp',
       'WebDataSourceImpl.cpp',
       'WebDataSourceImpl.h',
       'WebDatabase.cpp',
diff --git a/third_party/WebKit/public/blink_headers.gypi b/third_party/WebKit/public/blink_headers.gypi
index 398fdf82..a3747be 100644
--- a/third_party/WebKit/public/blink_headers.gypi
+++ b/third_party/WebKit/public/blink_headers.gypi
@@ -359,7 +359,6 @@
       "web/WebDOMMediaStreamTrack.h",
       "web/WebDOMMessageEvent.h",
       "web/WebDOMProgressEvent.h",
-      "web/WebDOMResourceProgressEvent.h",
       "web/WebDataSource.h",
       "web/WebDatabase.h",
       "web/WebDateTimeChooserCompletion.h",
diff --git a/third_party/WebKit/public/web/WebDOMResourceProgressEvent.h b/third_party/WebKit/public/web/WebDOMResourceProgressEvent.h
deleted file mode 100644
index 9736e8f..0000000
--- a/third_party/WebKit/public/web/WebDOMResourceProgressEvent.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef WebDOMResourceProgressEvent_h
-#define WebDOMResourceProgressEvent_h
-
-#include "WebDOMProgressEvent.h"
-
-namespace blink {
-
-class WebString;
-
-class WebDOMResourceProgressEvent : public WebDOMProgressEvent {
-public:
-    WebDOMResourceProgressEvent() { }
-    BLINK_EXPORT WebDOMResourceProgressEvent(const WebString& type, bool lengthIsComputable, unsigned long long loaded, unsigned long long total, const WebString& url);
-};
-
-} // namespace blink
-
-#endif
diff --git a/third_party/WebKit/public/web/WebElement.h b/third_party/WebKit/public/web/WebElement.h
index 012fe328..ae356e5 100644
--- a/third_party/WebKit/public/web/WebElement.h
+++ b/third_party/WebKit/public/web/WebElement.h
@@ -59,7 +59,6 @@
     // namespace. Tag name matching is case-insensitive.
     BLINK_EXPORT bool hasHTMLTagName(const WebString&) const;
     BLINK_EXPORT bool hasAttribute(const WebString&) const;
-    BLINK_EXPORT void removeAttribute(const WebString&);
     BLINK_EXPORT WebString getAttribute(const WebString&) const;
     BLINK_EXPORT bool setAttribute(const WebString& name, const WebString& value);
     BLINK_EXPORT WebString textContent() const;
diff --git a/third_party/WebKit/public/web/WebImageCache.h b/third_party/WebKit/public/web/WebImageCache.h
index 8dcdd4e..22a524c 100644
--- a/third_party/WebKit/public/web/WebImageCache.h
+++ b/third_party/WebKit/public/web/WebImageCache.h
@@ -35,8 +35,6 @@
 
 namespace blink {
 
-// An interface to query and configure WebKit's image cache.
-//
 // Methods of this interface can be called on any thread.
 //
 // Methods of this interface can be only be used after blink::initialize()
@@ -44,19 +42,10 @@
 
 class WebImageCache {
 public:
-    // Sets the capacities of the image cache, evicting objects as necessary.
-    BLINK_EXPORT static void setCacheLimitInBytes(size_t);
-
     // Clears the cache (as much as possible; some resources may not be
     // cleared if they are actively referenced).
     BLINK_EXPORT static void clear();
 
-    // Returns the number of bytes used by the cache.
-    BLINK_EXPORT static size_t memoryUsageInBytes();
-
-    // Returns the number of cached entries.
-    BLINK_EXPORT static unsigned cacheEntries();
-
 private:
     WebImageCache();  // Not intended to be instanced.
 };
diff --git a/third_party/WebKit/public/web/WebOptionElement.h b/third_party/WebKit/public/web/WebOptionElement.h
index bc98f98..01c00e6 100644
--- a/third_party/WebKit/public/web/WebOptionElement.h
+++ b/third_party/WebKit/public/web/WebOptionElement.h
@@ -31,14 +31,13 @@
 #ifndef WebOptionElement_h
 #define WebOptionElement_h
 
-#include "../platform/WebVector.h"
 #include "WebElement.h"
 
 namespace blink {
 
 class HTMLOptionElement;
+class WebString;
 
-// Provides readonly access to some properties of a DOM option element node.
 class WebOptionElement final : public WebElement {
 public:
     WebOptionElement() : WebElement() { }
@@ -51,13 +50,9 @@
     }
     void assign(const WebOptionElement& element) { WebElement::assign(element); }
 
-    BLINK_EXPORT void setValue(const WebString&);
     BLINK_EXPORT WebString value() const;
-
-    BLINK_EXPORT int index() const;
     BLINK_EXPORT WebString text() const;
     BLINK_EXPORT WebString label() const;
-    BLINK_EXPORT bool isEnabled() const;
 
 #if BLINK_IMPLEMENTATION
     WebOptionElement(const PassRefPtrWillBeRawPtr<HTMLOptionElement>&);
diff --git a/third_party/WebKit/public/web/WebPluginContainer.h b/third_party/WebKit/public/web/WebPluginContainer.h
index aff88c6..b757702 100644
--- a/third_party/WebKit/public/web/WebPluginContainer.h
+++ b/third_party/WebKit/public/web/WebPluginContainer.h
@@ -59,6 +59,8 @@
     // Returns the element containing this plugin.
     virtual WebElement element() = 0;
 
+    virtual void dispatchProgressEvent(const WebString& type, bool lengthComputable, unsigned long long loaded, unsigned long long total, const WebString& url) = 0;
+
     virtual void invalidate() = 0;
     virtual void invalidateRect(const WebRect&) = 0;
     virtual void scrollRect(const WebRect&) = 0;
diff --git a/third_party/libjingle/README.chromium b/third_party/libjingle/README.chromium
index b135b34d..9ee3b5d 100644
--- a/third_party/libjingle/README.chromium
+++ b/third_party/libjingle/README.chromium
@@ -1,7 +1,7 @@
 Name: libjingle
 URL: http://www.webrtc.org
 Version: unknown
-Revision: 10646
+Revision: 10659
 License: BSD
 License File: source/talk/COPYING
 Security Critical: yes
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index c0391ce..d37d8921 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -47990,6 +47990,14 @@
   </summary>
 </histogram>
 
+<histogram name="TabManager.Discarding.InactiveToReloadTime" units="ms">
+  <owner>georgesak@chromium.org</owner>
+  <summary>
+    Elapsed time between the time a tab switched from being active to inactive
+    (that eventually gets discarded) until it gets reloaded.
+  </summary>
+</histogram>
+
 <histogram name="TabManager.Discarding.ReloadCount" units="Reloads">
   <owner>georgesak@chromium.org</owner>
   <summary>
@@ -58667,6 +58675,7 @@
   <int value="308" label="Default printer selection rules"/>
   <int value="309" label="Allow Dinosaur Easter Egg Game"/>
   <int value="310" label="Whether RC4 cipher suites in TLS are enabled"/>
+  <int value="311" label="Default value for Display Rotation"/>
 </enum>
 
 <enum name="EnterprisePolicyInvalidations" type="int">
@@ -75842,7 +75851,7 @@
   <int value="10" label="kDefaultSearchProviderName"/>
   <int value="11" label="kPinnedTabs"/>
   <int value="12" label="kKnownDisabled (Obsolete 07/2014)"/>
-  <int value="13" label="kProfileResetPromptMemento"/>
+  <int value="13" label="kProfileResetPromptMemento (Obsolete 11/2015)"/>
   <int value="14" label="kDefaultSearchProviderDataPrefName"/>
   <int value="15" label="kPreferenceResetTime"/>
   <int value="16" label="kSafeBrowsingIncidentReportSent"/>
diff --git a/ui/android/java/src/org/chromium/ui/base/ActivityWindowAndroid.java b/ui/android/java/src/org/chromium/ui/base/ActivityWindowAndroid.java
index ad02b45..615b0ab 100644
--- a/ui/android/java/src/org/chromium/ui/base/ActivityWindowAndroid.java
+++ b/ui/android/java/src/org/chromium/ui/base/ActivityWindowAndroid.java
@@ -41,7 +41,6 @@
 
     private static final String PERMISSION_QUERIED_KEY_PREFIX = "HasRequestedAndroidPermission::";
 
-    private final WeakReference<Activity> mActivityRef;
     private final Handler mHandler;
     private final SparseArray<PermissionCallback> mOutstandingPermissionRequests;
 
@@ -63,8 +62,7 @@
      * @param listenToActivityState Whether to listen to activity state changes.
      */
     public ActivityWindowAndroid(Activity activity, boolean listenToActivityState) {
-        super(activity.getApplicationContext());
-        mActivityRef = new WeakReference<Activity>(activity);
+        super(activity);
         mHandler = new Handler();
         mOutstandingPermissionRequests = new SparseArray<PermissionCallback>();
         if (listenToActivityState) {
@@ -76,16 +74,16 @@
 
     @Override
     protected void registerKeyboardVisibilityCallbacks() {
-        Activity activity = mActivityRef.get();
+        Activity activity = getActivity().get();
         if (activity == null) return;
         View content = activity.findViewById(android.R.id.content);
-        mIsKeyboardShowing = UiUtils.isKeyboardShowing(mActivityRef.get(), content);
+        mIsKeyboardShowing = UiUtils.isKeyboardShowing(getActivity().get(), content);
         content.addOnLayoutChangeListener(this);
     }
 
     @Override
     protected void unregisterKeyboardVisibilityCallbacks() {
-        Activity activity = mActivityRef.get();
+        Activity activity = getActivity().get();
         if (activity == null) return;
         activity.findViewById(android.R.id.content).removeOnLayoutChangeListener(this);
     }
@@ -93,7 +91,7 @@
     @Override
     public int showCancelableIntent(
             PendingIntent intent, IntentCallback callback, Integer errorId) {
-        Activity activity = mActivityRef.get();
+        Activity activity = getActivity().get();
         if (activity == null) return START_INTENT_FAILURE;
 
         int requestCode = generateNextRequestCode();
@@ -111,7 +109,7 @@
 
     @Override
     public int showCancelableIntent(Intent intent, IntentCallback callback, Integer errorId) {
-        Activity activity = mActivityRef.get();
+        Activity activity = getActivity().get();
         if (activity == null) return START_INTENT_FAILURE;
 
         int requestCode = generateNextRequestCode();
@@ -128,7 +126,7 @@
 
     @Override
     public void cancelIntent(int requestCode) {
-        Activity activity = mActivityRef.get();
+        Activity activity = getActivity().get();
         if (activity == null) return;
         activity.finishActivity(requestCode);
     }
@@ -190,7 +188,7 @@
      */
     public boolean onRequestPermissionsResult(int requestCode, String[] permissions,
             int[] grantResults) {
-        Activity activity = mActivityRef.get();
+        Activity activity = getActivity().get();
         assert activity != null;
 
         SharedPreferences.Editor editor =
@@ -209,8 +207,7 @@
 
     @Override
     public WeakReference<Activity> getActivity() {
-        // Return a new WeakReference to prevent clients from releasing our internal WeakReference.
-        return new WeakReference<Activity>(mActivityRef.get());
+        return new WeakReference<Activity>((Activity) getContext().get());
     }
 
     @Override
@@ -225,7 +222,7 @@
     @Override
     public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft,
             int oldTop, int oldRight, int oldBottom) {
-        keyboardVisibilityPossiblyChanged(UiUtils.isKeyboardShowing(mActivityRef.get(), v));
+        keyboardVisibilityPossiblyChanged(UiUtils.isKeyboardShowing(getActivity().get(), v));
     }
 
     private int generateNextRequestCode() {
@@ -251,7 +248,7 @@
         public boolean canRequestPermission(String permission) {
             if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return false;
 
-            Activity activity = mActivityRef.get();
+            Activity activity = getActivity().get();
             if (activity == null) return false;
 
             if (isPermissionRevokedByPolicy(permission)) {
@@ -275,7 +272,7 @@
         public boolean isPermissionRevokedByPolicy(String permission) {
             if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return false;
 
-            Activity activity = mActivityRef.get();
+            Activity activity = getActivity().get();
             if (activity == null) return false;
 
             return activity.getPackageManager().isPermissionRevokedByPolicy(
@@ -311,7 +308,7 @@
         private boolean requestPermissionsInternal(
                 String[] permissions, PermissionCallback callback) {
             if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return false;
-            Activity activity = mActivityRef.get();
+            Activity activity = getActivity().get();
             if (activity == null) return false;
 
             int requestCode = generateNextRequestCode();
diff --git a/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java b/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java
index 3d775de1..658d0be 100644
--- a/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java
+++ b/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java
@@ -77,6 +77,8 @@
 
     protected Context mApplicationContext;
     protected SparseArray<IntentCallback> mOutstandingIntents;
+    // We use a weak reference here to prevent this from leaking in WebView.
+    private WeakReference<Context> mContextRef;
 
     // Ideally, this would be a SparseArray<String>, but there's no easy way to store a
     // SparseArray<String> in a bundle during saveInstanceState(). So we use a HashMap and suppress
@@ -136,13 +138,20 @@
      */
     @SuppressLint("UseSparseArrays")
     public WindowAndroid(Context context) {
-        assert context == context.getApplicationContext();
-        mApplicationContext = context;
+        mApplicationContext = context.getApplicationContext();
+        // context does not have the same lifetime guarantees as an application context so we can't
+        // hold a strong reference to it.
+        mContextRef = new WeakReference<Context>(context);
         mOutstandingIntents = new SparseArray<IntentCallback>();
         mIntentErrors = new HashMap<Integer, String>();
         mVSyncMonitor = new VSyncMonitor(context, mVSyncListener);
-        mAccessibilityManager = (AccessibilityManager)
-                context.getSystemService(Context.ACCESSIBILITY_SERVICE);
+        mAccessibilityManager = (AccessibilityManager) mApplicationContext.getSystemService(
+                Context.ACCESSIBILITY_SERVICE);
+    }
+
+    @CalledByNative
+    private static WindowAndroid createForTesting(Context context) {
+        return new WindowAndroid(context);
     }
 
     /**
@@ -584,6 +593,16 @@
     }
 
     /**
+     * Getter for the current context (not necessarily the application context).
+     * Make no assumptions regarding what type of Context is returned here, it could be for example
+     * an Activity or a Context created specifically to target an external display.
+     */
+    public WeakReference<Context> getContext() {
+        // Return a new WeakReference to prevent clients from releasing our internal WeakReference.
+        return new WeakReference<Context>(mContextRef.get());
+    }
+
+    /**
      * Update whether the placeholder is 'drawn' based on whether an animation is running
      * or touch exploration is enabled - if either of those are true, we call
      * setWillNotDraw(false) to ensure that the animation is drawn over the SurfaceView,
diff --git a/ui/android/java/src/org/chromium/ui/resources/ResourceManager.java b/ui/android/java/src/org/chromium/ui/resources/ResourceManager.java
index da3d254..3e96bbb 100644
--- a/ui/android/java/src/org/chromium/ui/resources/ResourceManager.java
+++ b/ui/android/java/src/org/chromium/ui/resources/ResourceManager.java
@@ -13,6 +13,8 @@
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.JNINamespace;
 import org.chromium.base.annotations.MainDex;
+import org.chromium.ui.base.WindowAndroid;
+import org.chromium.ui.gfx.DeviceDisplayInfo;
 import org.chromium.ui.resources.ResourceLoader.ResourceLoaderCallback;
 import org.chromium.ui.resources.dynamics.DynamicResource;
 import org.chromium.ui.resources.dynamics.DynamicResourceLoader;
@@ -37,33 +39,51 @@
 
     private long mNativeResourceManagerPtr;
 
-    private ResourceManager(Context context, long staticResourceManagerPtr) {
-        Resources resources = context.getResources();
+    private ResourceManager(
+            Resources resources, int minScreenSideLength, long staticResourceManagerPtr) {
         mPxToDp = 1.f / resources.getDisplayMetrics().density;
 
-        // Register ResourceLoaders
         registerResourceLoader(new StaticResourceLoader(
                 AndroidResourceType.STATIC, this, resources));
         registerResourceLoader(new DynamicResourceLoader(
                 AndroidResourceType.DYNAMIC, this));
         registerResourceLoader(new DynamicResourceLoader(
                 AndroidResourceType.DYNAMIC_BITMAP, this));
-        registerResourceLoader(new SystemResourceLoader(
-                AndroidResourceType.SYSTEM, this, context));
+        registerResourceLoader(
+                new SystemResourceLoader(AndroidResourceType.SYSTEM, this, minScreenSideLength));
         mCrushedSpriteResourceLoader = new CrushedSpriteResourceLoader(this, resources);
 
         mNativeResourceManagerPtr = staticResourceManagerPtr;
     }
 
     /**
-     * Creates an instance of a {@link ResourceManager}.  This will
-     * @param context                  A {@link Context} instance to grab {@link Resources} from.
+     * Creates an instance of a {@link ResourceManager}.
+     * @param WindowAndroid            A {@link WindowAndroid} instance to fetch a {@link Context}
+     * and thus grab {@link Resources} from.
      * @param staticResourceManagerPtr A pointer to the native component of this class.
      * @return                         A new instance of a {@link ResourceManager}.
      */
     @CalledByNative
-    private static ResourceManager create(Context context, long staticResourceManagerPtr) {
-        return new ResourceManager(context, staticResourceManagerPtr);
+    private static ResourceManager create(
+            WindowAndroid windowAndroid, long staticResourceManagerPtr) {
+        Context context = windowAndroid.getContext().get();
+        // This call should happen early enough (i.e. during construction) that this context should
+        // not yet have been released.
+        if (context == null) {
+            throw new IllegalStateException("Context should not be null during initialization.");
+        }
+
+        DeviceDisplayInfo displayInfo = DeviceDisplayInfo.create(context);
+        int screenWidth = displayInfo.getPhysicalDisplayWidth() != 0
+                ? displayInfo.getPhysicalDisplayWidth()
+                : displayInfo.getDisplayWidth();
+        int screenHeight = displayInfo.getPhysicalDisplayHeight() != 0
+                ? displayInfo.getPhysicalDisplayHeight()
+                : displayInfo.getDisplayHeight();
+        int minScreenSideLength = Math.min(screenWidth, screenHeight);
+
+        Resources resources = context.getResources();
+        return new ResourceManager(resources, minScreenSideLength, staticResourceManagerPtr);
     }
 
     /**
diff --git a/ui/android/java/src/org/chromium/ui/resources/system/SystemResourceLoader.java b/ui/android/java/src/org/chromium/ui/resources/system/SystemResourceLoader.java
index 9039ac23..0cbedf5 100644
--- a/ui/android/java/src/org/chromium/ui/resources/system/SystemResourceLoader.java
+++ b/ui/android/java/src/org/chromium/ui/resources/system/SystemResourceLoader.java
@@ -4,7 +4,6 @@
 
 package org.chromium.ui.resources.system;
 
-import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
@@ -12,7 +11,6 @@
 import android.graphics.Paint.Style;
 import android.graphics.RectF;
 
-import org.chromium.ui.gfx.DeviceDisplayInfo;
 import org.chromium.ui.resources.Resource;
 import org.chromium.ui.resources.SystemUIResourceType;
 import org.chromium.ui.resources.async.AsyncPreloadResourceLoader;
@@ -30,19 +28,19 @@
      * @param resourceType The resource type this loader is responsible for loading.
      * @param callback     The {@link ResourceLoaderCallback} to notify when a {@link Resource} is
      *                     done loading.
-     * @param resources    A {@link Resources} instance to load assets from.
+     * @param minScreenSideLengthPx    The length (in pixels) of the smallest side of the screen.
      */
-    public SystemResourceLoader(int resourceType, ResourceLoaderCallback callback,
-            final Context context) {
+    public SystemResourceLoader(
+            int resourceType, ResourceLoaderCallback callback, final int minScreenSideLengthPx) {
         super(resourceType, callback, new ResourceCreator() {
             @Override
             public Resource create(int resId) {
-                return createResource(context, resId);
+                return createResource(minScreenSideLengthPx, resId);
             }
         });
     }
 
-    private static Resource createResource(Context context, int resId) {
+    private static Resource createResource(int minScreenSideLengthPx, int resId) {
         switch (resId) {
             case SystemUIResourceType.OVERSCROLL_EDGE:
                 return StaticResource.create(Resources.getSystem(),
@@ -51,7 +49,7 @@
                 return StaticResource.create(Resources.getSystem(),
                         getResourceId("android:drawable/overscroll_glow"), 128, 64);
             case SystemUIResourceType.OVERSCROLL_GLOW_L:
-                return createOverscrollGlowLBitmap(context);
+                return createOverscrollGlowLBitmap(minScreenSideLengthPx);
 
             default:
                 assert false;
@@ -59,14 +57,8 @@
         return null;
     }
 
-    private static Resource createOverscrollGlowLBitmap(Context context) {
-        DeviceDisplayInfo displayInfo = DeviceDisplayInfo.create(context);
-        int screenWidth = displayInfo.getPhysicalDisplayWidth() != 0
-                ? displayInfo.getPhysicalDisplayWidth() : displayInfo.getDisplayWidth();
-        int screenHeight = displayInfo.getPhysicalDisplayHeight() != 0
-                ? displayInfo.getPhysicalDisplayHeight() : displayInfo.getDisplayHeight();
-
-        float arcWidth = Math.min(screenWidth, screenHeight) * 0.5f / SIN_PI_OVER_6;
+    private static Resource createOverscrollGlowLBitmap(int minScreenSideLengthPx) {
+        float arcWidth = minScreenSideLengthPx * 0.5f / SIN_PI_OVER_6;
         float y = COS_PI_OVER_6 * arcWidth;
         float height = arcWidth - y;
 
diff --git a/ui/android/resources/resource_manager_impl.cc b/ui/android/resources/resource_manager_impl.cc
index a4f2373..c5dd3b6 100644
--- a/ui/android/resources/resource_manager_impl.cc
+++ b/ui/android/resources/resource_manager_impl.cc
@@ -13,6 +13,7 @@
 #include "cc/resources/scoped_ui_resource.h"
 #include "jni/ResourceManager_jni.h"
 #include "ui/android/resources/ui_resource_provider.h"
+#include "ui/android/window_android.h"
 #include "ui/gfx/android/java_bitmap.h"
 #include "ui/gfx/geometry/rect.h"
 
@@ -27,11 +28,13 @@
                                         jobj));
 }
 
-ResourceManagerImpl::ResourceManagerImpl() : host_(nullptr) {
+ResourceManagerImpl::ResourceManagerImpl(gfx::NativeWindow native_window)
+    : host_(nullptr) {
   JNIEnv* env = base::android::AttachCurrentThread();
   java_obj_.Reset(env, Java_ResourceManager_create(
-                           env, base::android::GetApplicationContext(),
-                           reinterpret_cast<intptr_t>(this)).obj());
+                           env, native_window->GetJavaObject().obj(),
+                           reinterpret_cast<intptr_t>(this))
+                           .obj());
   DCHECK(!java_obj_.is_null());
 }
 
diff --git a/ui/android/resources/resource_manager_impl.h b/ui/android/resources/resource_manager_impl.h
index 04d59cc..4618a36 100644
--- a/ui/android/resources/resource_manager_impl.h
+++ b/ui/android/resources/resource_manager_impl.h
@@ -9,6 +9,7 @@
 #include "ui/android/resources/resource_manager.h"
 #include "ui/android/ui_android_export.h"
 #include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/native_widget_types.h"
 
 namespace ui {
 
@@ -16,7 +17,7 @@
  public:
   static ResourceManagerImpl* FromJavaObject(jobject jobj);
 
-  ResourceManagerImpl();
+  explicit ResourceManagerImpl(gfx::NativeWindow native_window);
   ~ResourceManagerImpl() override;
 
   void Init(cc::LayerTreeHost* host);
diff --git a/ui/android/resources/resource_manager_impl_unittest.cc b/ui/android/resources/resource_manager_impl_unittest.cc
index dbf2e65a..fd57f70 100644
--- a/ui/android/resources/resource_manager_impl_unittest.cc
+++ b/ui/android/resources/resource_manager_impl_unittest.cc
@@ -12,6 +12,7 @@
 #include "third_party/skia/include/core/SkCanvas.h"
 #include "ui/android/resources/resource_manager_impl.h"
 #include "ui/android/resources/system_ui_resource_type.h"
+#include "ui/android/window_android.h"
 #include "ui/gfx/android/java_bitmap.h"
 
 
@@ -34,7 +35,9 @@
 
 class TestResourceManagerImpl : public ResourceManagerImpl {
  public:
-  TestResourceManagerImpl() {}
+  TestResourceManagerImpl(WindowAndroid* window_android)
+      : ResourceManagerImpl(window_android) {}
+
   ~TestResourceManagerImpl() override {}
 
   void SetResourceAsLoaded(AndroidResourceType res_type, int res_id) {
@@ -80,7 +83,10 @@
 
 class ResourceManagerTest : public testing::Test {
  public:
-  ResourceManagerTest() : fake_client_(cc::FakeLayerTreeHostClient::DIRECT_3D) {
+  ResourceManagerTest()
+      : window_android_(WindowAndroid::createForTesting()),
+        resource_manager_(window_android_),
+        fake_client_(cc::FakeLayerTreeHostClient::DIRECT_3D) {
     cc::LayerTreeHost::InitParams params;
     cc::LayerTreeSettings settings;
     params.client = &fake_client_;
@@ -90,6 +96,8 @@
     resource_manager_.Init(host_.get());
   }
 
+  ~ResourceManagerTest() override { window_android_->Destroy(NULL, NULL); }
+
   void PreloadResource(ui::SystemUIResourceType type) {
     resource_manager_.PreloadResource(ui::ANDROID_RESOURCE_TYPE_SYSTEM, type);
   }
@@ -104,6 +112,9 @@
                                           type);
   }
 
+ private:
+  WindowAndroid* window_android_;
+
  protected:
   scoped_ptr<MockLayerTreeHost> host_;
   TestResourceManagerImpl resource_manager_;
diff --git a/ui/android/window_android.cc b/ui/android/window_android.cc
index 5fe7779..0ba6e6cc 100644
--- a/ui/android/window_android.cc
+++ b/ui/android/window_android.cc
@@ -38,6 +38,13 @@
   DCHECK(!compositor_);
 }
 
+WindowAndroid* WindowAndroid::createForTesting() {
+  JNIEnv* env = AttachCurrentThread();
+  jobject context = base::android::GetApplicationContext();
+  return new WindowAndroid(
+      env, Java_WindowAndroid_createForTesting(env, context).obj());
+}
+
 void WindowAndroid::OnCompositingDidCommit() {
   FOR_EACH_OBSERVER(WindowAndroidObserver,
                     observer_list_,
diff --git a/ui/android/window_android.h b/ui/android/window_android.h
index 58f1e28..f08b2f2 100644
--- a/ui/android/window_android.h
+++ b/ui/android/window_android.h
@@ -69,6 +69,8 @@
   // Return whether the specified Android permission can be requested by Chrome.
   bool CanRequestPermission(const std::string& permission);
 
+  static WindowAndroid* createForTesting();
+
  private:
   ~WindowAndroid();
 
diff --git a/ui/aura/window_tree_host_platform.cc b/ui/aura/window_tree_host_platform.cc
index 10c5013..409f92a 100644
--- a/ui/aura/window_tree_host_platform.cc
+++ b/ui/aura/window_tree_host_platform.cc
@@ -49,8 +49,7 @@
 
 WindowTreeHostPlatform::WindowTreeHostPlatform()
     : widget_(gfx::kNullAcceleratedWidget),
-      current_cursor_(ui::kCursorNull),
-      has_capture_(false) {}
+      current_cursor_(ui::kCursorNull) {}
 
 void WindowTreeHostPlatform::SetPlatformWindow(
     scoped_ptr<ui::PlatformWindow> window) {
@@ -91,15 +90,11 @@
 }
 
 void WindowTreeHostPlatform::SetCapture() {
-  if (!has_capture_) {
-    has_capture_ = true;
-    window_->SetCapture();
-  }
+  window_->SetCapture();
 }
 
 void WindowTreeHostPlatform::ReleaseCapture() {
-  if (has_capture_)
-    window_->ReleaseCapture();
+  window_->ReleaseCapture();
 }
 
 void WindowTreeHostPlatform::SetCursorNative(gfx::NativeCursor cursor) {
@@ -164,10 +159,7 @@
     ui::PlatformWindowState new_state) {}
 
 void WindowTreeHostPlatform::OnLostCapture() {
-  if (has_capture_) {
-    has_capture_ = false;
-    OnHostLostWindowCapture();
-  }
+  OnHostLostWindowCapture();
 }
 
 void WindowTreeHostPlatform::OnAcceleratedWidgetAvailable(
diff --git a/ui/aura/window_tree_host_platform.h b/ui/aura/window_tree_host_platform.h
index 18b8e4d..b885e73 100644
--- a/ui/aura/window_tree_host_platform.h
+++ b/ui/aura/window_tree_host_platform.h
@@ -60,7 +60,6 @@
   gfx::AcceleratedWidget widget_;
   scoped_ptr<ui::PlatformWindow> window_;
   gfx::NativeCursor current_cursor_;
-  bool has_capture_;
   gfx::Rect bounds_;
 
   DISALLOW_COPY_AND_ASSIGN(WindowTreeHostPlatform);
diff --git a/ui/base/clipboard/clipboard_mac.mm b/ui/base/clipboard/clipboard_mac.mm
index 62331947..306502f 100644
--- a/ui/base/clipboard/clipboard_mac.mm
+++ b/ui/base/clipboard/clipboard_mac.mm
@@ -307,8 +307,21 @@
   // may throw, and that exception will leak. Prevent a crash in that case;
   // a blank image is better.
   base::scoped_nsobject<NSImage> image;
+  NSPasteboard* pb = GetPasteboard();
   @try {
-    image.reset([[NSImage alloc] initWithPasteboard:GetPasteboard()]);
+    if ([[pb types] containsObject:NSFilenamesPboardType]) {
+      // -[NSImage initWithPasteboard:] gets confused with copies of a single
+      // file from the Finder, so extract the path ourselves.
+      // http://crbug.com/553686
+      NSArray* paths = [pb propertyListForType:NSFilenamesPboardType];
+      if ([paths count]) {
+        // If N number of files are selected from finder, choose the last one.
+        image.reset([[NSImage alloc]
+            initWithContentsOfURL:[NSURL fileURLWithPath:[paths lastObject]]]);
+      }
+    } else {
+      image.reset([[NSImage alloc] initWithPasteboard:pb]);
+    }
   } @catch (id exception) {
   }
 
diff --git a/ui/gfx/display.h b/ui/gfx/display.h
index 650c95f..b355c1a8d 100644
--- a/ui/gfx/display.h
+++ b/ui/gfx/display.h
@@ -23,6 +23,8 @@
 class GFX_EXPORT Display {
  public:
   // Screen Rotation in clock-wise degrees.
+  // This enum corresponds to DisplayRotationDefaultProto::Rotation in
+  // chrome/browser/chromeos/policy/proto/chrome_device_policy.proto.
   enum Rotation {
     ROTATE_0 = 0,
     ROTATE_90,
diff --git a/ui/gl/BUILD.gn b/ui/gl/BUILD.gn
index 1131722..6d101e37 100644
--- a/ui/gl/BUILD.gn
+++ b/ui/gl/BUILD.gn
@@ -344,10 +344,6 @@
     sources += [ "glx_api_unittest.cc" ]
   }
 
-  if (use_ozone) {
-    sources += [ "gl_image_ozone_native_pixmap_unittest.cc" ]
-  }
-
   include_dirs = [ "//third_party/khronos" ]
 
   deps = [
diff --git a/ui/gl/gl_image_egl.cc b/ui/gl/gl_image_egl.cc
index c130832..91800e2 100644
--- a/ui/gl/gl_image_egl.cc
+++ b/ui/gl/gl_image_egl.cc
@@ -56,9 +56,7 @@
 
 bool GLImageEGL::BindTexImage(unsigned target) {
   DCHECK(thread_checker_.CalledOnValidThread());
-  if (egl_image_ == EGL_NO_IMAGE_KHR)
-    return false;
-
+  DCHECK_NE(EGL_NO_IMAGE_KHR, egl_image_);
   glEGLImageTargetTexture2DOES(target, egl_image_);
   DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
   return true;
diff --git a/ui/gl/gl_image_ozone_native_pixmap_unittest.cc b/ui/gl/gl_image_ozone_native_pixmap_unittest.cc
deleted file mode 100644
index a21a444..0000000
--- a/ui/gl/gl_image_ozone_native_pixmap_unittest.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/buffer_types.h"
-#include "ui/gl/gl_image_ozone_native_pixmap.h"
-#include "ui/gl/test/gl_image_test_template.h"
-#include "ui/ozone/public/ozone_platform.h"
-#include "ui/ozone/public/surface_factory_ozone.h"
-
-namespace gl {
-namespace {
-
-class GLImageOzoneNativePixmapTestDelegate {
- public:
-  scoped_refptr<gl::GLImage> CreateSolidColorImage(
-      const gfx::Size& size,
-      const uint8_t color[4]) const {
-    ui::SurfaceFactoryOzone* surface_factory =
-        ui::OzonePlatform::GetInstance()->GetSurfaceFactoryOzone();
-    scoped_refptr<ui::NativePixmap> pixmap =
-        surface_factory->CreateNativePixmap(gfx::kNullAcceleratedWidget, size,
-                                            gfx::BufferFormat::RGBA_8888,
-                                            gfx::BufferUsage::SCANOUT);
-    EXPECT_TRUE(pixmap != nullptr);
-    scoped_refptr<gfx::GLImageOzoneNativePixmap> image(
-        new gfx::GLImageOzoneNativePixmap(size, GL_RGBA));
-    EXPECT_TRUE(image->Initialize(pixmap.get(), pixmap->GetBufferFormat()));
-    return image;
-  }
-};
-
-INSTANTIATE_TYPED_TEST_CASE_P(GLImageOzoneNativePixmap,
-                              GLImageTest,
-                              GLImageOzoneNativePixmapTestDelegate);
-
-}  // namespace
-}  // namespace gl
diff --git a/ui/gl/gl_tests.gyp b/ui/gl/gl_tests.gyp
index 9b09ad81..d369723 100644
--- a/ui/gl/gl_tests.gyp
+++ b/ui/gl/gl_tests.gyp
@@ -54,11 +54,6 @@
             'wgl_api_unittest.cc',
           ],
         }],
-        ['use_ozone==1', {
-          'sources': [
-            'gl_image_ozone_native_pixmap_unittest.cc',
-          ],
-        }],
       ],
     }
   ],
diff --git a/ui/login/account_picker/screen_account_picker.css b/ui/login/account_picker/screen_account_picker.css
index d90210a..66f079e 100644
--- a/ui/login/account_picker/screen_account_picker.css
+++ b/ui/login/account_picker/screen_account_picker.css
@@ -8,6 +8,10 @@
                       height 180ms ease;
 }
 
+#bubble {
+  z-index: 1;
+}
+
 #signin-banner-container1 {
   bottom: 100%;
   margin-bottom: 10px;
diff --git a/ui/ozone/platform/cast/client_native_pixmap_factory_cast.cc b/ui/ozone/platform/cast/client_native_pixmap_factory_cast.cc
index a55c3462..3f7100a 100644
--- a/ui/ozone/platform/cast/client_native_pixmap_factory_cast.cc
+++ b/ui/ozone/platform/cast/client_native_pixmap_factory_cast.cc
@@ -4,51 +4,12 @@
 
 #include "ui/ozone/platform/cast/client_native_pixmap_factory_cast.h"
 
-#include "base/logging.h"
-#include "ui/gfx/buffer_types.h"
-#include "ui/ozone/public/client_native_pixmap.h"
-#include "ui/ozone/public/client_native_pixmap_factory.h"
+#include "ui/ozone/common/stub_client_native_pixmap_factory.h"
 
 namespace ui {
-namespace {
-
-// Dummy ClientNativePixmap implementation for Cast ozone.
-// Our NativePixmaps are just used to plumb an overlay frame through,
-// so they get instantiated, but not used.
-class ClientNativePixmapCast : public ClientNativePixmap {
- public:
-  // ClientNativePixmap implementation:
-  void* Map() override {
-    NOTREACHED();
-    return nullptr;
-  }
-  void Unmap() override { NOTREACHED(); }
-  void GetStride(int* stride) const override { NOTREACHED(); }
-};
-
-class ClientNativePixmapFactoryCast : public ClientNativePixmapFactory {
- public:
-  // ClientNativePixmapFactoryCast implementation:
-  void Initialize(base::ScopedFD device_fd) override {}
-
-  bool IsConfigurationSupported(gfx::BufferFormat format,
-                                gfx::BufferUsage usage) const override {
-    return format == gfx::BufferFormat::RGBA_8888 &&
-           usage == gfx::BufferUsage::SCANOUT;
-  }
-
-  scoped_ptr<ClientNativePixmap> ImportFromHandle(
-      const gfx::NativePixmapHandle& handle,
-      const gfx::Size& size,
-      gfx::BufferUsage usage) override {
-    return make_scoped_ptr(new ClientNativePixmapCast());
-  }
-};
-
-}  // namespace
 
 ClientNativePixmapFactory* CreateClientNativePixmapFactoryCast() {
-  return new ClientNativePixmapFactoryCast();
+  return CreateStubClientNativePixmapFactory();
 }
 
 }  // namespace ui
diff --git a/ui/ozone/platform/cast/surface_factory_cast.cc b/ui/ozone/platform/cast/surface_factory_cast.cc
index 1d4bee3b..174dd78 100644
--- a/ui/ozone/platform/cast/surface_factory_cast.cc
+++ b/ui/ozone/platform/cast/surface_factory_cast.cc
@@ -69,8 +69,7 @@
 
 void SurfaceFactoryCast::TerminateDisplay() {
   void* egl_lib_handle = egl_platform_->GetEglLibrary();
-  if (!egl_lib_handle)
-    return;
+  DCHECK(egl_lib_handle);
 
   EGLGetDisplayFn get_display =
       reinterpret_cast<EGLGetDisplayFn>(dlsym(egl_lib_handle, "eglGetDisplay"));
@@ -189,7 +188,7 @@
       // TODO(halliwell): try to implement this through CastEglPlatform.
       return nullptr;
     }
-    int GetDmaBufFd() override { return -1; }
+    int GetDmaBufFd() override { return 0; }
     int GetDmaBufPitch() override { return 0; }
     gfx::BufferFormat GetBufferFormat() override {
       return gfx::BufferFormat::LAST;
diff --git a/ui/ozone/platform/headless/headless_surface_factory.cc b/ui/ozone/platform/headless/headless_surface_factory.cc
index 1b7b956c..3262e69 100644
--- a/ui/ozone/platform/headless/headless_surface_factory.cc
+++ b/ui/ozone/platform/headless/headless_surface_factory.cc
@@ -16,7 +16,6 @@
 #include "ui/gfx/vsync_provider.h"
 #include "ui/ozone/platform/headless/headless_window.h"
 #include "ui/ozone/platform/headless/headless_window_manager.h"
-#include "ui/ozone/public/native_pixmap.h"
 #include "ui/ozone/public/surface_ozone_canvas.h"
 
 namespace ui {
@@ -66,40 +65,6 @@
   skia::RefPtr<SkSurface> surface_;
 };
 
-class TestPixmap : public ui::NativePixmap {
- public:
-  TestPixmap(gfx::BufferFormat format) : format_(format) {}
-
-  void* GetEGLClientBuffer() override { return nullptr; }
-  int GetDmaBufFd() override { return -1; }
-  int GetDmaBufPitch() override { return 0; }
-  gfx::BufferFormat GetBufferFormat() override { return format_; }
-  bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
-                            int plane_z_order,
-                            gfx::OverlayTransform plane_transform,
-                            const gfx::Rect& display_bounds,
-                            const gfx::RectF& crop_rect) override {
-    return true;
-  }
-  void SetProcessingCallback(
-      const ProcessingCallback& processing_callback) override {}
-  scoped_refptr<NativePixmap> GetProcessedPixmap(
-      gfx::Size target_size,
-      gfx::BufferFormat target_format) override {
-    return nullptr;
-  }
-  gfx::NativePixmapHandle ExportHandle() override {
-    return gfx::NativePixmapHandle();
-  }
-
- private:
-  ~TestPixmap() override {}
-
-  gfx::BufferFormat format_;
-
-  DISALLOW_COPY_AND_ASSIGN(TestPixmap);
-};
-
 }  // namespace
 
 HeadlessSurfaceFactory::HeadlessSurfaceFactory()
@@ -123,12 +88,4 @@
   return false;
 }
 
-scoped_refptr<NativePixmap> HeadlessSurfaceFactory::CreateNativePixmap(
-    gfx::AcceleratedWidget widget,
-    gfx::Size size,
-    gfx::BufferFormat format,
-    gfx::BufferUsage usage) {
-  return new TestPixmap(format);
-}
-
 }  // namespace ui
diff --git a/ui/ozone/platform/headless/headless_surface_factory.h b/ui/ozone/platform/headless/headless_surface_factory.h
index 1f008ed..b715cbcc 100644
--- a/ui/ozone/platform/headless/headless_surface_factory.h
+++ b/ui/ozone/platform/headless/headless_surface_factory.h
@@ -24,11 +24,6 @@
   bool LoadEGLGLES2Bindings(
       AddGLLibraryCallback add_gl_library,
       SetGLGetProcAddressProcCallback set_gl_get_proc_address) override;
-  scoped_refptr<NativePixmap> CreateNativePixmap(
-      gfx::AcceleratedWidget widget,
-      gfx::Size size,
-      gfx::BufferFormat format,
-      gfx::BufferUsage usage) override;
 
  private:
   HeadlessWindowManager* window_manager_;
diff --git a/ui/platform_window/win/win_window.cc b/ui/platform_window/win/win_window.cc
index 1c6e4a974..802f2d79 100644
--- a/ui/platform_window/win/win_window.cc
+++ b/ui/platform_window/win/win_window.cc
@@ -90,8 +90,8 @@
 }
 
 void WinWindow::SetCapture() {
-  DCHECK(::GetCapture() != hwnd());
-  ::SetCapture(hwnd());
+  if (::GetCapture() != hwnd())
+    ::SetCapture(hwnd());
 }
 
 void WinWindow::ReleaseCapture() {
diff --git a/ui/views/window/dialog_delegate.cc b/ui/views/window/dialog_delegate.cc
index ce4cced..ee50da9 100644
--- a/ui/views/window/dialog_delegate.cc
+++ b/ui/views/window/dialog_delegate.cc
@@ -7,6 +7,7 @@
 #include "base/logging.h"
 #include "ui/accessibility/ax_view_state.h"
 #include "ui/base/l10n/l10n_util.h"
+#include "ui/gfx/color_palette.h"
 #include "ui/strings/grit/ui_strings.h"
 #include "ui/views/bubble/bubble_border.h"
 #include "ui/views/bubble/bubble_frame_view.h"
@@ -199,7 +200,7 @@
   const BubbleBorder::Shadow kShadow = BubbleBorder::SMALL_SHADOW;
 #endif
   scoped_ptr<BubbleBorder> border(
-      new BubbleBorder(BubbleBorder::FLOAT, kShadow, SK_ColorRED));
+      new BubbleBorder(BubbleBorder::FLOAT, kShadow, gfx::kPlaceholderColor));
   border->set_use_theme_background_color(true);
   frame->SetBubbleBorder(border.Pass());
   DialogDelegate* delegate = widget->widget_delegate()->AsDialogDelegate();